如何使用OO和SOLID原则更好地设计?

时间:2016-08-18 15:04:28

标签: oop solid-principles

我发现很多关于相关问题的类似帖子,taylonr的回复很接近,但没有完全回答我的情况。

假设我有一个界面:

public interface IShape
{
    decimal GetArea();
}

然后我使用此界面创建3个类

public class Rectangle : IShape
{
    public decimal GetArea()
    {
        ...
    }
}

public class Triangle : IShape
{
    public decimal GetArea()
    {
        ...
    }
}

public class Circle : IShape
{
    public decimal GetArea()
    {
        ...
    }
}

我现在想要添加一个int GetNumberOfSides()函数(或其他一些仅与我的一些IShape相关的函数)。显然这与Circle类没有关系。如果我有一个List<IShape>个对象,并希望在相关的IShapes上迭代调用此函数,那么如何使用面向对象的设计原则来解决这个问题?

我可以在我的IShape接口bool HasSides { get; set; }中添加一个布尔值并运行其中的任何逻辑,但是我需要转换为特定的类才能访问GetNumberOfSides()函数。我知道这不是正确的,因为它感觉不对,但我不知道该怎么做。

我已经考虑过从ISidedShape继承的另一个接口IShape,但是回到我的列表的迭代,我怎么知道哪个形状有这个特定的方法?

非常感谢任何帮助。

由于

3 个答案:

答案 0 :(得分:1)

如果你想要去OOP路线,你可以添加一个界面,因为你可以在大多数语言中实现任意多个:

public interface IPolygon
{
    int GetNumberOfSides();
}

public class Rectangle : IShape, IPolygon
{
    public decimal GetArea() { return 0; }
    public int GetNumberOfSides() { return 4; }
}

确实,所有多边形都是形状;然而,在过去的几年里,许多OOPer都认为继承既强大又极其危险,而且一般来说,复合关系比分层关系更有意义。

我觉得有必要说,虽然这是一个很好的学术练习,但是典型的&#34;形状&#34; OOP示例通常不能很好地转化为现实世界&#34;因此,许多程序员发现自己过于复杂,否则可能是一个简单的方法。由于一切都必须是一个对象,我们被迫将数据映射到对象模型,这通常意味着我们强制将数据与范例相匹配或开发构造以使事情有效,而不是简单地处理数据。 &#34;简单&#34;是国王,复杂性是敌人。

答案 1 :(得分:0)

如果你的代码中某些地方已经有List<IShape>(所以你依赖IShape多态性),我会说最好的解决办法就是GetNumberOfSides()添加IShape 1}}并将其实现为

public class Circle : IShape
{
    public decimal GetNumberOfSides()
    {
        return 0;
    }
}

如果您仍处于“设计”阶段并且实际上没有使用List<IShape>的代码,则可以实现第二个接口IPolygon(完全像@Josh回答)。

这两种解决方案中的任何一种都适合(取决于当前使用IShape的方式)和“OOP方法”。我不能说哪一个更好,因为你没有向我们展示你的真实代码(根据形状示例做出这样的决定并不相关)。

然而,我唯一不鼓励的做法是在hasSides中添加IShape方法,因为每次迭代{{}}时,您的代码很快会被大量if混乱{1}}因此将成为测试和维护的噩梦。因此,请让多态性处理分支,而不是在List<IShape>上使用if手动分支。

答案 2 :(得分:0)

它符合LSP和IS原则 如果将方法getSides()添加到IShape接口,那么当Circle实现该接口时它将违反LSP,因为它没有边。 所以你想在帖子中创建一个新的IPolygon接口,这样它就会跟随Is和LSP