小智 5
实体不应有行为。它们代表数据,数据本身是被动的。我目前正在从事一个遗留项目,该遗留项目已将实体的行为纳入其中,这是一场噩梦,没人想碰代码。
您可以在我的博客文章:面向对象的反模式-具有行为的数据对象上阅读更多内容。
属性和行为
对象由属性和行为组成,但是数据对象从定义上仅代表数据,因此只能具有属性。书籍,电影,文件,甚至IO流都没有行为。一本书有标题,但不知道如何阅读。电影有演员,但不知道怎么玩。文件包含内容,但不知道如何删除。流具有内容,但是它不知道如何打开/关闭或停止。这些都是具有属性但没有行为的数据对象的示例。因此,应将它们视为愚蠢的数据对象,而我们作为软件工程师不应将行为强加于它们。
传递数据而不是行为
数据对象在不同的执行环境中移动,但是行为应该被封装,并且通常只与一个环境有关。在任何应用程序中,数据都会被传递,解析,操纵,持久化,检索,序列化,反序列化等等。例如,实体通常从休眠层传递到服务层,再传递到前端层,然后再返回。在分布式系统中,它可能会通过多个管道,队列,缓存并最终进入新的执行上下文。属性可以应用于所有三个层,但是特定的行为(例如保存,解析,序列化)仅在各个层才有意义。因此,向数据对象添加行为会违反封装,模块化甚至安全原则。
代码如下:
book.Write();
book.Print();
book.Publish();
book.Buy();
book.Open();
book.Read();
book.Highlight();
book.Bookmark();
book.GetRelatedBooks();
Run Code Online (Sandbox Code Playgroud)
可以这样重构:
Book book = author.WriteBook();
printer.Print(book);
publisher.Publish(book);
customer.Buy(book);
reader = new BookReader();
reader.Open(Book);
reader.Read();
reader.Highlight();
reader.Bookmark();
librarian.GetRelatedBooks(book);
Run Code Online (Sandbox Code Playgroud)
自然的面向对象建模可以带来多大的不同!我们从单一的怪异的Book类转变为六个独立的类,每个类负责各自的行为。
这使代码:
| 归档时间: |
|
| 查看次数: |
1495 次 |
| 最近记录: |