我最近阅读了一个关于OOP相关问题的有趣评论,其中一个用户反对创建"Manager"类:
在谈论课程名称时,请从词汇表中删除单词manager.该类的名称应该描述其目的.经理只是倾销的另一个词.任何功能都适合那里.这个词一直是许多极端糟糕设计的原因
这个评论体现了我努力成为一个优秀的面向对象的开发人员.我一直在一个只有程序编码人员的组织里做过程序代码.看起来我们生成的相对较少的OO代码背后的主要策略是将问题分解为易于识别为离散单元的类,然后将左侧/广义位放在"Manager"类中.
我怎样才能打破我的程序习惯(比如Manager类)?大多数OO文章/书籍等使用本质上易于转换为对象组的问题的示例(例如,车辆 - >汽车),因此不提供用于分解更复杂系统的大量指导.
首先,我会停止表现得像程序代码是错误的.这是一些适合某些工作的工具.OO也是一些工作的正确工具.功能也是如此.每个范例只是计算的不同观点,并且存在是因为它对某些问题很方便,而不是因为它是唯一正确的编程方式.原则上,所有三个范例在数学上都是等价的,因此请使用最佳映射到问题域的任何一个.恕我直言,如果使用多范式语言,如果不同的世界观最好地模拟不同的子问题,甚至可以在模块中混合范例.
其次,我会阅读设计模式.没有一些现实世界问题的例子很难理解OO它有利于解决.Head First Design Patterns是一个很好的阅读,因为它回答了很多OO的"原因".
成为优秀的OO需要多年的实践和学习良好的OO代码,理想情况下是导师.请记住,OO只是达到目的的一种手段.话虽如此,这里有一些适合我的一般指导方针:
赞成合成而不是继承.阅读并重新阅读GoF书籍的第一章.
遵守得墨忒耳法则("告诉,不要问")
尝试仅使用继承来实现多态.当您从另一个类扩展一个类时,请注意您将通过对基类的引用来调用该类的行为.基类的所有公共方法都应该对子类有意义.
不要挂在建模上.构建工作原型以通知您的设计.
拥抱重构.阅读福勒书中的前几章.
该单一职责原则帮助我打破对象为管理类,是有意义的.
每个对象应该做一件事,并且做得很好,而不会将其内部工作方式暴露给需要使用它的其他对象.
"经理"课程通常会:
插入某种状态
根据该州做出决定
作为一种解药或对比,面向对象的设计会鼓励你设计类API,你可以"告诉不要问"类本身自己做事(以及封装自己的状态):更多关于"告诉不要" 不要问"看到这里和这里(也许其他人对"告诉不要问"有更好的解释,但这些是Google为我找到的前两篇文章).
看起来我们生成的小OO代码的主要策略是将问题分解为易于识别为离散单元的类,然后将左侧/广义位放在"Manager"类中.
即使在最好的时候,这可能也是如此.Coplien在他的高级C++:编程风格和成语书的结尾处谈到了这一点:他说在一个系统中,你倾向于:
自包含的物体
而且,"交易",作用于其他对象
以一架飞机为例(我很抱歉给你另一个车辆示例;我正在解释他):
"物体"可能包括副翼,方向舵和推力
'manager'或autpilot将实现各种命令或事务
例如,"向右转"交易包括:
flaps.right.up()
flaps.left.down()
rudder.right()
thrust.increase()
所以我认为你的交易是真实的,它可以跨越或使用各种相对被动的"对象"; 例如,在应用程序中,"whatever"用户命令最终将由每个层(例如UI,中间层和DB层)实现(并因此调用)各种对象.
所以我认为在某种程度上你会留下"遗留物"; 但这是一个程度问题:或许你应该尽可能多地希望代码是自包含的,封装的,以及所有其他东西......以及剩余的东西,它们使用(或依赖于)其他一切,应该给予/使用尽可能隐藏且尽可能多的API,因此尽可能多地承担远离所谓的经理的责任(实施细节).
不幸的是,我只在一本书(高级C++)中读到了这个概念,并且不能将你链接到网上,以获得比我的这个释义更清楚的解释.
阅读然后练习OO原则对我有用.首先是面向对象的分析和设计,通过示例为您提供OO解决方案,然后提供更好的解决方案.
通过研究设计模式,您可以学习良好的面向对象设计原则. Code Complete 2是一本很好的书,可以阅读这个主题.自然地,将良好的编程原则融入到您的脑海中的最佳方法是通过将它们应用于您自己的编码项目来不断地实践它们.