如何确保特定对象仅由另一个对象实例化?

时间:2012-12-11 07:09:38

标签: php design-patterns registry

如何确保仅通过另一个特定对象实例化对象?

例如,假设我有一个Registry对象来存储我的Mappers。当客户端代码调用Registry上的get()方法时,它会延迟加载并返回请求的Mapper。这很好,除了没有什么可以阻止客户端代码使用new运算符创建Mapper的重复实例。

我能想到的唯一选择是我的Mappers需要一个Registry对象作为参数。还有其他选择吗?

你做什么的?我是否应该为防止这种重复而烦恼?

3 个答案:

答案 0 :(得分:1)

也许您不应该试图阻止人们自己创建实例?如果您不相信自己或您的同事不在不应该实例化的地方实例化对象,那么您就会遇到问题。

如果映射器不需要注册表来运行,则不应通过构造函数对其进行对象。将它传递给某个静态方法似乎很奇怪,并且因为你使用静态而使你的代码变得不那么灵活。你是如何对映射器进行单元测试的,而不是编写一些黑客来通过注册表正确实例化它们在这些测试中你不应该需要它们?关于这方面的好帖子:http://kore-nordmann.de/blog/0103_static_considered_harmful.html

答案 1 :(得分:0)

您无法保护new运营商。你可以做的是你的类中有一个get()方法来制作你的类/对象单例(或者像你一样使用注册表)。

class clTest {
 private static $oInstance;

 public static function get() {
  if( !self::$oInstance ) {
   self::$oInstance = new clText;
  }

  return self::$oInstance;
 }
}

答案 2 :(得分:0)

如果您希望阻止外部实例化,您只需要将__construct声明为private,然后使用对静态方法的调用来获取Mapper类的实例。然后,您可以传入注册表类的实例,并且只有在参数是注册表类的实例时才返回新实例。

class Mapper{
  private __construct(){}

  public static function getInstance($registry){
    if($registry instanceof Registry){
      return new Mapper();
    }
  }
}

$registry = new Registry();
$mapper = Mapper::getInstance($registry);