Oop 实体是否应该有行为?
实体应该有行为吗?还是不 为什么Oop 实体是否应该有行为?,oop,Oop,实体应该有行为吗?还是不 为什么 如果没有,这是否违反了封装?如果您严格遵循MVC,您的模型(实体)将不会有任何固有的行为。然而,我确实包含了任何可以最容易地管理实体持久性的助手方法,包括有助于维护其与其他实体关系的方法。这取决于它们是什么类型的实体——但术语“实体”至少对我来说意味着业务实体,在这种情况下它们应该有行为 “业务实体”是真实世界对象的建模,它应该封装对象表示在软件上下文中的所有业务逻辑(行为)和属性/数据。如果您的实体没有行为,那么您就没有编写面向对象的代码。如果一切都是用get
如果没有,这是否违反了封装?如果您严格遵循MVC,您的模型(实体)将不会有任何固有的行为。然而,我确实包含了任何可以最容易地管理实体持久性的助手方法,包括有助于维护其与其他实体关系的方法。这取决于它们是什么类型的实体——但术语“实体”至少对我来说意味着业务实体,在这种情况下它们应该有行为
“业务实体”是真实世界对象的建模,它应该封装对象表示在软件上下文中的所有业务逻辑(行为)和属性/数据。如果您的实体没有行为,那么您就没有编写面向对象的代码。如果一切都是用getter和setter完成的,而没有其他行为,那么您就是在编写过程代码
很多商店都保持沉默。他们的理由是数据结构很少改变,但业务逻辑却改变了。这是一种谬论。有很多模式可以解决这个问题,它们不涉及将所有东西都简化为一袋袋的getter和setter。如果你计划将你的实体暴露于世界,你最好(通常)将行为与实体隔离。如果您想集中您的业务操作(即ValidateEndorOrder),您不希望Order有一个IsValid()方法,该方法运行一些逻辑来验证自身。您不希望在客户端上运行该代码(如果他们捏造了该代码会怎样。例如,类似于不提供任何客户端UI来设置购物车中商品的价格,而是在URL上发布虚假价格。如果您没有服务器端验证,那就不好!复制该验证是…多余的…干的(不要重复自己) 另一个实体上的行为不起作用的例子是延迟加载的概念。今天的许多ORM都允许您在访问实体上的属性时延迟加载数据。如果您正在构建一个三层应用程序,这根本不起作用,因为您的客户机在访问pr时最终会无意中尝试进行数据库调用不动产
这些是我头脑中最重要的参数,用于阻止实体的行为。实体不应该有行为。它们表示数据,而数据本身是被动的。 我目前正在从事一个遗留项目,它包含了实体中的行为,这是一个噩梦,没有人想碰它 您可以在我的博客上阅读更多内容:
[预览]面向对象反模式-具有行为的数据对象:
属性和行为 对象由属性和行为组成,但根据定义,数据对象只表示数据,因此只能具有属性。书籍、电影、文件甚至IO流都没有行为。书籍有标题,但不知道如何阅读。电影有演员,但不知道如何播放。文件有内容,但不知道如何播放删除。流有内容,但它不知道如何打开/关闭或停止。这些都是具有属性但不具有行为的数据对象的示例。因此,它们应被视为哑数据对象,我们作为软件工程师不应将行为强加给它们
传递数据而不是行为 数据对象在不同的执行环境中移动,但是行为应该被封装,并且通常只与一个环境相关。在任何应用程序中,数据都会被传递、解析、操作、持久化、检索、序列化、反序列化等等。例如,一个实体通常从hibernate层传递到在分布式系统中,它可能会通过几个管道、队列、缓存,并最终进入一个新的执行上下文。属性可以应用于所有三个层,但特定行为(如保存、解析、序列化)仅在各个层中才有意义。因此,向数据对象添加行为违反了封装、模块化甚至安全原则
这样编写的代码:
book.Write();
book.Print();
book.Publish();
book.Buy();
book.Open();
book.Read();
book.Highlight();
book.Bookmark();
book.GetRelatedBooks();
可以这样重构:
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);
自然的面向对象建模能带来多大的不同啊!我们从一个庞大的图书类变成了六个独立的类,每个类负责各自的行为
这使得代码:
- 更容易阅读和理解,因为它更自然
- 更容易更新,因为功能包含在更小的封装类中
- 更灵活,因为我们可以轻松地用重写版本替换六个单独类中的一个或多个
- 更容易测试,因为功能是分离的,并且更容易模拟