Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 实体是否应该有行为?_Oop - Fatal编程技术网

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);  
自然的面向对象建模能带来多大的不同啊!我们从一个庞大的图书类变成了六个独立的类,每个类负责各自的行为

这使得代码:

  • 更容易阅读和理解,因为它更自然
  • 更容易更新,因为功能包含在更小的封装类中
  • 更灵活,因为我们可以轻松地用重写版本替换六个单独类中的一个或多个
  • 更容易测试,因为功能是分离的,并且更容易模拟

在什么上下文中,您指的是实体?基于ORM的实体还是独立域对象?实体不是数据对象,在重构示例中,读取器很容易成为实体。