9

如果你有很多类,其中只有 1 或 2 个方法,这是否是糟糕设计的标志?

我正在尝试学习 OOP 设计并创建了一个小型应用程序(很小)。

它最终得到了很多实现接口的类,这些接口只包含 1 或 2 个方法。

分离的感觉很好,但是类的方法太少似乎很糟糕。

我知道每种情况都会有所不同,但从一般角度来看这很糟糕吗?

应用程序的一小部分决定了喂狗的时间表(我知道跛脚):

所以我试图在这里实现策略模式:

class DogFeedController
{
    protected $strategy = null;

    public function __construct(iDogFeedStrategy $strategy) {
        $this->strategy = $strategy;
    }

    public function getFeedingSchedule() {
        $morningFeeds = $this->strategy->generateMorningFeeds();
        $eveningFeeds = $this->strategy->generateEveningFeeds();       
    }

}


class GeneralFeedStrategy implements iDogFeedStrategy
{
    public function generateMorningFeeds() {
        //do stuff here
    }

    public function generateEveningFeeds() {
        //do stuff here
    }
}
4

5 回答 5

8

如果太多,您必须自己衡量。OOP 是一种以有意义且真实的方式分离逻辑的好方法,但它也可能达到对可维护性产生负面影响的程度,并且在那时它被错误地应用。

想想应用程序的去向。它总是会是一个小应用程序吗?如果是这样,您不需要创建很多非常通用的接口。尝试将它们结合起来,如果只有一个类实现了接口,你也许可以完全删除接口。

如果您预计您的应用程序将大幅增长,那么这些接口实际上可能会帮助您在未来维护和添加功能。例如,如果您创建了一个应用程序来管理一个只有汽车停车位的停车场,如果您预计会增长到不同类型的车辆(例如摩托车只占用一半停车位),您可能希望创建一个通用汽车界面。也就是说,您不应该试图在项目开始时涵盖所有可能的需求变化,并使代码过于抽象。衡量需求变化的风险可以帮助您预测需要抽象哪些代码。

如果您是团队中的软件工程师,请将您的设计绘制成图表并将其展示给您的同事,以征求他们的意见。

最后,小心代码异味

于 2012-08-23T17:29:16.820 回答
7

从一般的角度来看,具有太大或相反太小的类都被认为是一种不好的做法,并被称为所谓的Code Smells。我指的两个是大型类(又名God Object)和懒惰类(又名Freeloader)。

以下是来自WikipediaCoding Horror的定义:

大类:一个已经变得太大的类。

大型类,如长方法,难以阅读、理解和排除故障。类是否包含太多职责?大班可以重组或分成小班吗?

懒惰类:做得太少的类。

课程应该发挥作用。每增加一个类都会增加项目的复杂性。如果您有一个班级没有为自己付出足够的努力,是否可以将其折叠或合并到另一个班级中?

另一方面,面向对象设计有一个原则,称为接口隔离原则,它指出“不应强迫客户依赖他们不使用的方法”。在您的情况下,具有较少方法的接口实际上确实符合此原则。

综上所述,您的设计非常正确。具有较少方法的接口是好的,因此实现这些接口的类不必实现所有方法以及它们不使用的方法。至于类,我相信最终它们会变得更大。请记住,实现接口并不意味着您不能拥有比已实现接口中定义的方法更多的方法。也就是说,尝试在那里放置更多逻辑。

更多关于SOLID(面向对象的设计原则)的信息,可以在Wikipedia上找到。

PS。Code Smells 是糟糕设计的症状,而 SOLID 是治疗方法。

于 2012-08-23T18:22:16.230 回答
3

我认为你应该问自己的问题是。这个类是否对它正在做的事情负责?能够识别和分离职责是 OOP 的基石。例如,您可以拥有一个Security只有一种方法来创建随机密码的类。

我认为(这是我的观点)如果随机密码仅在寄存器中使用,而不是创建该类的私有方法,我会将该方法分成一个新类Security,因为我不认为那是Register班级的责任。

此外,由于您的应用程序很小,每个类的方法很少是完全正常的。


编辑:看到你的代码我可以提出一些建议,但请记住,我看不到整个画面。

如果你没有,你应该阅读MVC 模式,你的应用程序中可能没有视图,但是将控制器与模型分离是一个很好的做法。

DogFeedController似乎是一个控制器和GeneralFeedStrategy模型。我喜欢用他们的名字来结束我的班级的名字。例如UserControllerUserViewUserModel。我认为这使事情变得清楚,但同样,这是我的观点。

我看不到拥有的意义,iDogFeedStrategy但我没有看到整个图片。接口的基本用途是保证一组类,无论它们有多么不同,都具有相同的API,并封装了实现接口的每个类的细节。

于 2012-08-23T17:25:20.850 回答
0

除了关注点分离之外,OOP 的另一个重要方面是类内聚。班级应该“自力更生”,而不是让许多其他东西称之为“吸气剂”,并对信息做一些事情。如果您想要多态行为,或者如果您计划在未来扩展您的应用程序,请创建接口。不要仅仅为了分离而创建接口。如果接口没有被两个或多个子类实现,请摆脱它们。(你也可以使用接口来应用依赖倒置原则,打破依赖循环)

OOP 中的设计决策应始终有意识地解决特定问题。否则,保持简单。

于 2012-08-23T17:41:29.087 回答
0

更喜欢大量具有复杂关系的小对象,而不是少数具有简单关系的大对象,因为这有利于可维护性,并且为将来的变化做好准备。

你的设计在我看来非常好,更何况考虑到你现在开始编程,而初学者总是反过来做。

于 2015-05-19T15:48:28.047 回答