我意识到这个问题已经存在一年了。但是我觉得其他答案没有解决 POJO 的主要问题。
回答您的问题:“POJO 是否反面向对象 (OO)?”。
不是和是的。
简单的答案说明
不,因为 OO 是关于您需要的建模概念。 POJO 正是这样做的。它将信息位捆绑到一个对象中。
是的,因为在 OO 中使用了一些 POJO 违反的原则。比如tell don't ask-原理。
详细解答说明
POJO 只是数据容器。你不会告诉 POJO 做任何事情。它只是一些信息的表示。因此,您询问它的当前状态。这意味着你违反了tell dont ask。
然而,这在某一时刻是不可避免的。就像函数式编程语言引入 IO 定义来指定函数不是“纯”的一样。你将不得不走出你整洁的小 OO-bubble 程序来询问事情......呃......外面......
包装你的 POJO
这就是我将 POJO 包装在模型中的原因(命名取决于您喜欢什么,我称它们为模型)。您可以通过扩展(就像克劳斯在他的回答中所做的那样)或组合(我更喜欢)来做到这一点。哪一个会让你心动。
POJO 定义了一个真实/抽象的数据源(您并不总是对真实的东西建模)。
实现告诉不要问
然后将其传递给负责操作 POJO 的 DataModel。
它通过被“告知”操作 POJO 来做到这一点。我这样做的原因是因为有时 POJO 包含类型信息。
因此直接操作 POJO 往往会导致某些 Class 不得不检查 POJO 的类型。
经常做这样的事情:
if(POJO.type == "something"){
this.doSmthWithPOJO();
}
现在你可能会得到一大堆不同类型的 POJO。在这种情况下,你可能会得到这样的结果:
if(POJO.type == "something"){
this.doSomethingWithPOJO(POJO);
}
else if (POJO.type == "something else")
{
this.doSomethingElseWithPOJO(POJO);
}
else if( POJO.type == "something else entirely")
{
this.doSomethingElseEntirelyWithPOJO(POJO);
}
else{
this.print("This is starting to get ugly...");
}
您这样做是因为 POJO 中的类型信息意味着您必须做一些稍微不同的事情。将 POJO 包含在 DataModel 中并带有您可以调用的函数,可以让您做一些更清洁的事情。同时将操作或类型检查的责任转移到课堂之外。
POJOTypeDataModel model = new POJOTypeDataModel(POJO);
然后上面的 If-elseif-else-statement 因为要简单得多。
model.doSomething();
正如我上面提到的,您将不得不在某一时刻询问“POJO.type”。
当我第一次需要数据源时,我会这样做。数据源调用返回 POJO。您检查它的类型并返回一个 DataModel 而不是 POJO。
需要强调的是,您只需检查一次 POJO 的类型!在您检索/创建 POJO 并将其包装的那一刻。
如果 POJO 没有被包装或没有专门键入,您将不得不更多地询问 POJO 的类型。这使使用 POJO 的类的原始意图变得混乱。
它还去掉了很多 if 语句。
此外,您还鼓励使用抽象而不是特定类型。
简而言之
执行上述操作可以帮助您:
- 把外面放在外面。因为 POJO 通常是数据源。
- 尽可能坚持
tell don't ask。
- 鼓励使用抽象而不是具体类型(不能比 POJO 更具体)。
- 编写更简洁(您不会到处进行类型检查)并且更易于理解代码(众所周知,人们不擅长理解大量程序代码)。
- 最终,包装可以帮助您避免更改代码。因为您可能在代码中的任何地方都对 POJO 进行类型检查(参见 if 示例)。现在您只需在 DataModel 上调用一个函数,它就知道该做什么了。
回到简单的答案
您无法避免向 POJO 询问信息。然而,它非常适合对数据源进行建模。
因此,包装它并使用抽象来调用 DataModel 可以限制违反某些核心 OO 原则,并且可以使代码更整洁。