学习面向对象设计

10

我读过《Head First Java》,了解面向对象编程的工作原理。我的问题是:我是PHP程序员,虽然我已经在PHP中使用了面向对象编程,但我不知道什么应该是一个对象以及应该赋予它哪些方法。

例如,假设我有一个应用程序,允许用户登录并编辑文档。如果只会有一个文档实例,那么为什么文档需要成为一个对象呢?我应该把deleteDocument()方法给文档对象还是管理员对象?文档是被删除的,但行动执行者是管理员。

所以,我的真正问题是,作为一个过程化编程背景的人,我该如何确定哪些应该是对象,并决定应该赋予它们哪些方法呢?

7个回答

5

在你的例子中,我不确定为什么你的设计中只有一个文档,但是为了以后可能需要更多的文档,它应该仍然是一个对象。

至于删除功能,没有一个简单明了的答案;你可能会发现双方都有争论。个人而言,我会把较低级别的删除功能(例如删除数据库条目)放在文档类内部,但其他任何功能都可以放在父类中。如果所有文档都归管理员所有,管理员应该有一个DeleteDocument函数,调用文档的删除功能,并从数据库中移除所有相关联的内容。

一般来说,如果你发现自己传递大量状态变量的数组或者声明了许多全局变量,那么就将与之相关的功能转化为一个类。尽可能使对象所包含的功能保持紧密相关,否则你可能会发现你的类膨胀得无法控制。


2

没有一种答案是普适的。如果你对面向对象设计感兴趣,我推荐阅读这本书

至于你如何确定哪些应该成为对象以及它们应该拥有哪些方法,一个好的启发式方法是问自己某种能力是否是成为某个物体所必需的。以下是我记得从我的面向对象编程课堂上的一个例子... 在应用程序中跟踪人员和宠物,那么人员类是否应该具有getPets()方法呢?嗯,拥有宠物是否是成为人的必要条件吗?不是。一个更好的解决方案可能是拥有一个代表宠物所有权的单独关系类。


1
+1,部分是为了推荐设计模式书籍 - 尽管我认为它在这里并没有真正帮助。设计模式书在某些方面打破了面向对象的常规规则 - 类不是独立的抽象,有时甚至看起来根本不是自己的抽象 - 它们是多类抽象中的组件(整个模式)。 - user180247

2

这将在一定程度上取决于您选择的编程语言。Java是一种“纯OO”语言,意味着无论您是否喜欢,所有内容都必须封装成类。C++是“不纯”的 - 如果您愿意,您可以决定您的文档只是一堆全局变量。

即使在C++中,您也经常会封装一些内容到类中,即使只有一个实例。这是因为类不仅仅是一种打包任意内容的方式 - 它是一种抽象机制。通过将相关的事物分组并给予组名称,您可以使代码更易读和可维护 - 重用是主要好处之一,但不是使用类的唯一原因。


1

那么我的真正问题是,作为一个过程化编程背景的人,我该如何确定什么应该是对象,什么应该有哪些方法?

从《Head First Java》中获得了一些关于OOP机制的理解后,我建议你现在研究一下良好OO设计的几个原则。网络上有很多材料,好的和坏的都有,但如果你喜欢《Head First Java》,我建议你拿一本优秀的《Head First OO Analysis & Design》。它将回答你很多问题,并包含一些像你在这里提到的场景的优秀示例。

在你完成这些之后,你可能想看看SOLID原则,然后(就像这里其他人已经推荐的那样)一些常见的OO设计模式


1

我建议你看一下如何设计面向对象的项目。那里的被采纳答案是一个好的参考。

我在进行初始设计(得到类图)时使用的步骤如下:

需求收集。与客户交谈并分解用例以定义软件应具备的功能。

撰写每个用例的叙述。

浏览叙述并突出名词(人、地点、物品)作为候选类,动词(行动)作为方法/行为。

丢弃重复的名词并分解共同功能。

创建类图。如果你是Java开发者,Sun的NetBeans 6.7有一个UML模块,可以进行绘图和往返工程,而且是免费的。Eclipse(一个开源的Java IDE)也有一个建模框架,但我没有使用过。你也可以尝试使用ArgoUML,这是一个开源工具。

应用OOD原则来组织你的类(分解共同功能,构建层次结构等)


0

'Document'是一种特殊类型的对象-实体。它可以持久化或从存储中删除的事实是一个独立的问题,应该由某个称为“数据访问层”的其他类处理。您的业务类(希望您有一些)将使用实体、dal和其他类来执行业务功能。

随着接口和泛型的引入,这已经远远超出了这个范围。


0

DeleteDocument 应该放在管理员对象中。

你使用它是因为它更少的繁琐 - 更好的智能感知,更灵活等。此外,它还具有线程优势。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接