发送自己的物体 - 一个好主意?

时间:2010-09-10 15:22:49

标签: oop class data-structures

在将对数据进行操作的函数移动到包含该数据的类时,您在哪里绘制线?例如,假设您有一个简单的类,它存储天气的描述,包括温度,湿度,风速和风向的变量,以及测量的时间。现在假设你有一个这个类的对象,你想把它传送给别人 - 另一个进程,另一台机器,等等。您是否将代码传输到对象本身 - 例如,通过向简单数据类添加Send(目标类型)方法?或者你是否将这种功能保存在可以通过介质发送和接收任何内容的单独类中 - 无论是网络,文件i / o,进程间通信还是类似的东西?

我的直觉是保持我的数据类简单并在我想传输它们时将它们包装起来 - 在序列化它们的类中,并使用他们理解的简单接口呈现发送器和接收器类。另一种方法似乎是将包括厨房水槽在内的所有东西都放入简单的数据类中 - 每个函数都可以对这些数据进行操作,但是间接的。简而言之,网络错误处理代码在我看来并不属于简单的数据类。

这对我来说显而易见,但我一直看到开发人员在他们的类上放置Send()方法。他们甚至将消息类告诉Send()本身,这对我来说似乎非常违反直觉;如果我在一张纸上写一封信,我不会告诉该报纸。我把信封在一个信封里然后交给邮递员,因为他有一辆面包车和一张地图。人们的想法是什么?

4 个答案:

答案 0 :(得分:8)

有效载荷物品本身的逻辑是什么:现在的风速是多少?

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

决定在某个地方发送有效载荷是有道理的:哦,这是一个新的天气价值,有人在那里关心。

然后是实际的网络资料。

有效负载可能需要能够序列化和反序列化。我没有看到其余任何一个是有效载荷的问题。 Send()必须有一个更好的地方。尤其是因为您可能会选择一次发送多个有效负载对象,并且它们不能全部相互发送。

答案 1 :(得分:6)

这不是一个简单的问题。我已经使用这两种方法完成了项目,总体而言,我更乐意使用“智能模型”方法,模型知道如何使用自己的数据做事情。

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

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

答案 2 :(得分:5)

在我的职业生涯中,我多次在这种设计问题上来回走动。现在,我似乎是你的目标,主要是因为我在现在的生活中做了很多SOA,最后我写了很多文章,这些文章只是序列化为各种各样的。有线格式,主要涉及XML和JSON。

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

答案 3 :(得分:2)

简短的回答是,这取决于您想要处理的下游影响。

一般来说,当有两种方式做某事时,通常意味着两种方式都有其优点。我想起了几个例子(SQL与NoSQL,自动与手动传输,交替与直流,客户端与服务器端等)。这样做的结果是,你必须让双方都有很多人提出有价值的意见。

所以你提出的问题是,对象什么时候可以操作自己的数据,何时需要将其分开。

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

另一方面,这确实使API更难使用,因为它并不总是显而易见的。这也会产生在多个位置创建相同策略的可能性(并且每个层最终实现一些缓存)

例如,如果在String类中不容易找到像Split和Join和Substring这样的字符串方法,而是在其他地方比如假设的Parse类,那么在我找到这个假设的Parse类之前我可能会有写了这些方法的多个蹩脚版本。一个现实生活中的例子是人们编写的方法与Math类中的方法相同,因为他们不知道它。

最后,如果您不想处理下游影响,那么更改Send方法的工作方式可能需要访问很多类,然后将其移动到外部类。< / p>

如果您不想处理意外实现自己的Send方法的人,并且您不想一直强化它,那么最好将放在类中。