OOP:组成和公共财产?

时间:2012-11-12 00:18:44

标签: php oop design-patterns composition

所以我想说我有一个由其他类组成的类。

class HttpRequest
{
public $session = new Session();
// .. the rest of the HttpRequest code
}

现在,我想通过HttpRequest类访问Session类,所以我正在使用组合。 但这是否违反了OOP封装法或数据隐藏法,规定所有属性都应受到保护,并通过setter和getter方法进行访问?

这是错的:

$request = new HttpRequest();
$request->session->set('id', 5);

或者我应该使用它:

$request = new HttpRequest();
$session = $request->getSession();
$session->set('id', 5);

封装说明属性应受到保护。 那么如何提供对内部类的访问呢?就正确的OOP而言,第一个例子是错误的吗?

3 个答案:

答案 0 :(得分:1)

有正当理由不允许直接访问该对象:

  • 允许操纵对象本身之外的对象。如果你公开了这个属性,你的代码的任何部分都可能会覆盖HttpRequest类上的$ session,并且你很难跟踪它。从数据保护的角度来看,封装可以确保只有对象的方法才能直接改变对象。
  • 允许您正常处理未设置该变量的大小写。如果由于某种原因,$ session没有在你的课程中设置 - 当你尝试在其上调用方法时,你会立即致命。如果将其包装在getter中,则可以检查该条件并动态创建该类的新实例。
  • 遵循真正的“OO”范式

然而,在某些情况下,我会说这样做是可以的。特别是如果您知道将始终设置该属性(并且不支持使用该对象的唯一方式)。

取决于如何访问属性,这也是有意义的。 Symfony2在其Request类中使用它。在这种情况下感觉很自然,因为“查询”“发布”和“请求”变量都是“ParameterBag”(美化数组)。但是,它们确实暴露了Session对象的getter - 可能是因为它是用例。

简而言之:它实际上取决于你将如何使用变量。在这种特殊情况下,我认为这并不重要。

答案 1 :(得分:0)

我喜欢你的第一个选项,(它是使用合成的选项),看起来有封装(我不知道是什么使得函数设置),但我想它是通过“组件”的功能修改一些属性“对象”会话“,该模式也称为”委托“。

另一方面,如果使用封装,则不能使用“public”,即允许为每个人修改。正因为如此,您使用了setter或getter,或者在您的代码中“set”

答案 2 :(得分:0)

我知道这是旧的,但我不会使用这些。您的HttpRequest对象确实需要保留在Session对象上,还是可以将Session对象传递给需要它的HttpRequest对象的某些函数? HttpRequest存储这个对象有很强的理由吗?