Oop 发送自己的对象-一个好主意?

Oop 发送自己的对象-一个好主意?,oop,class,data-structures,Oop,Class,Data Structures,当将对数据进行操作的函数移动到包含该数据的类中时,您在哪里划出界限?例如,假设您有一个简单的类,该类存储天气描述,其中包含温度、湿度、风速和方向以及测量时间的变量。现在假设你有一个这个类的对象,你想把它传输给其他人——另一个进程,另一台机器,等等。您是否将用于将对象传输到对象本身的代码放入了对象中?例如,通过向简单数据类添加Send(destination type)方法?或者,您是否将此类功能保留在单独的类中,这些类可以通过介质发送和接收任何内容—无论是网络、文件i/o、进程间通信还是任何类似

当将对数据进行操作的函数移动到包含该数据的类中时,您在哪里划出界限?例如,假设您有一个简单的类,该类存储天气描述,其中包含温度、湿度、风速和方向以及测量时间的变量。现在假设你有一个这个类的对象,你想把它传输给其他人——另一个进程,另一台机器,等等。您是否将用于将对象传输到对象本身的代码放入了对象中?例如,通过向简单数据类添加Send(destination type)方法?或者,您是否将此类功能保留在单独的类中,这些类可以通过介质发送和接收任何内容—无论是网络、文件i/o、进程间通信还是任何类似的内容

我的直觉是让我的数据类保持简单,并在我想要传输它们时将它们封装在类中,这些类将它们序列化,并为发送方和接收方类提供它们理解的简单接口。另一种选择似乎是将包括厨房水槽在内的所有东西都放在简单的数据类中——所有可能对该数据进行操作的函数,无论多么间接。简而言之,在我看来,网络错误处理代码不属于简单的数据类


这对我来说似乎很明显,但我一直看到开发人员在类中使用Send()方法。他们甚至告诉消息类自己发送()消息,这在我看来是非常违反直觉的;如果我在一张纸上写一封信,我不会告诉报纸自己寄。我把信包在信封里交给邮递员,因为他有一辆货车和一张地图。人们是怎么想的?

在我的职业生涯中,我曾多次就此类设计问题反复思考。现在,我站在你看来的位置,主要是因为我在我当前的生活中做了大量的SOA工作,我最终编写了很多分类,这些分类只存在于各种在线格式之间,主要涉及XML和JSON


当您进入“服务”世界时,类通常只是来回发送的数据的表示。因此,我通常将我的类分为两个逻辑桶,“保存数据的类”和“做事情的类”。我不知道我是否是唯一一个做这种事情的人,但这就是我所处的位置。

有效载荷项目本身有一个逻辑:现在的风速是多少

解释这些数据是有逻辑的:我们现在可以停靠这艘船了吗

决定将有效载荷发送到某个地方是有逻辑的:哦,这里有一个新的天气值,那边有人关心

然后是实际的网络内容


负载可能需要能够序列化和反序列化自身。我看不出任何其他问题是有效载荷的问题。Send()必须有更好的位置。不仅仅是因为您可能选择一次发送多个有效负载对象,而它们不能全部相互发送。

这不是一个简单的问题。我已经用这两种方法做过项目,总的来说,我更喜欢使用“智能模型”方法,在这种方法中,模型非常了解如何使用自己的数据

实现良好封装的原则之一是“告诉,不要问”——如果你告诉类对自己做些什么,那么除了类本身之外,没有人需要知道类内部表示的细节。这绝对是件好事。此外,我发现将逻辑放入类本身通常会导致更容易的代码重用——当其他人使用该类时,他们会很快发现它已经知道如何执行给定的操作


但是,我不希望这会打破我的应用程序层之间的界限。我不想让业务对象知道如何将自己表示为HTML——这是一个表示问题。所以在这种情况下,我想说,类应该知道如何以某种规范的方式表示自己,但它不应该知道关于网络的东西。实际的发送功能应该属于服务。

简单的回答是,它取决于您想要处理的下游影响

一般来说,当有两种方法做某事时,通常意味着两种方法都有各自的优点。脑海中浮现了几个例子(SQL与NoSQL、自动与手动传输、交流与直流、客户端与服务器端等)。这样做的结果是,你一定会让双方的许多人都持有有价值的观点

所以你提出的问题是什么时候一个对象可以操纵它自己的数据,什么时候我需要把它分离出来

就个人而言,我更喜欢保持may数据结构简单,其主要职责是保持数据一致性。操纵或使用此数据的责任将由其他类负责。这有助于我将政策和实施分开。例如,如果我想实现缓存策略,我只需要访问获取数据的层,而不需要访问存储或操作数据的对象

另一方面,这确实使API更难使用,因为它并不总是很明显的东西在哪里。这也造成了在多个位置创建相同策略的可能性(并且每个层最终都实现了一些缓存)

例如,如果像Split and Join和Substring这样的字符串方法在String类中不容易找到,而在其他地方,比如一个假设的解析类,很可能在我找到这个假设的解析类之前,我已经编写了这些方法的多个蹩脚版本。现实生活中的一个例子是,人们编写的方法与数学课上的方法相同,因为他们不知道

最后,如果您不想处理下游影响,那么更改Send方法的工作方式可能需要访问大量