当包含类是单例模式时,使用合成创建许多对象

ant*_*009 -2 java singleton single-instance object-composition

java version 1.7.0_65
Run Code Online (Sandbox Code Playgroud)

我有一个单例设计模式类.这将始终返回最初创建的同一实例.

但是,我遇到的问题是这个类需要从另一个类创建许多其他对象.我已经使用了这个组合(POI类的实例ArlabFacade).从这个单例实例中,客户端应该能够创建许多POI对象.而且我不想公开POI类的内部工作,一切都必须通过单例实例.

private static ArlabFacade mArlabFacade = null;
private POI mPoi; /* Should be able to create many object of this class */

private ArlabFacade(Context context) {     
        /* initialize properties */
        mContext = context;

        mPoi = null;
    }

public static ArlabFacade getInstance(Context context) {

        /* Create a synchronised singleton instance */
        ReentrantLock lock = new ReentrantLock();
        lock.lock();
        if(mArlabFacade == null) {
            mArlabFacade = new ArlabFacade(context);
        }
        lock.unlock();

        return mArlabFacade;
    }
Run Code Online (Sandbox Code Playgroud)

我尝试过做这样的事情,但它有两个问题.

1) I don't want to return the class instance of POI
2) because I only have a single instance the mPoi will be overwritten by the next client call to this function. 
Run Code Online (Sandbox Code Playgroud)

这个函数只会覆盖:

 public POI createNewPOI() {
        return mPoi = new POI();
    }
Run Code Online (Sandbox Code Playgroud)

有没有解决这个问题的设计模式?

Tho*_*ets 6

我有点困惑你到底想要实现的目标.它看起来像你想有一个工厂,即隐藏如何创建一个特定的类的对象的类.除非你有其他原因,否则在这种情况下不需要单身人士.

至于你的问题:

  1. 您也不是返回class实例,而是返回该类的对象.我认为这就是重点:创建POI对象蚂蚁返回它.我猜这个命名法有些混乱,所以请解释一下你的类实例的意思,以及为什么你不想返回它.

  2. 在工厂方法中,createNewPOI()您只需覆盖对最后创建的POI对象的引用,而不是对象本身.除非您的工厂类(或您的Singleton)正在使用POI对象本身,否则无需保留引用.您将对象返回给方法的调用者.之后你可以忘掉它:

.

public POI createNewPOI() {
    return new POI();
}
Run Code Online (Sandbox Code Playgroud)

您的代码还有一个问题:您在getInstance()方法中的锁定将无法正常工作.要让ReentrantLock完成其工作,必须在多个线程之间共享.在你的情况下,每个线程创建自己的锁副本,而不知道其他的theads.

最简单的方法是使方法同步:

public static synchronized ArlabFacade getInstance(Context context) {

    if(mArlabFacade == null) {
        mArlabFacade = new ArlabFacade(context);
    }

    return mArlabFacade;
}
Run Code Online (Sandbox Code Playgroud)

  • @ ant2009不,这不是很清楚.如果您不希望客户端了解POI类,那么为什么要提供返回POI对象的方法?POI类只是实现了一个接口吗?然后更改createPOI()方法以返回该接口.您是否仅在内部使用POI对象?然后不要将该方法放在公共接口中. (2认同)

Mar*_*gus 6

看看:单身人士有什么不好的?

如果有原因,您应该只使用代码模式.例如:opular模式和使用它们的原因是:

创作模式

  • Abstract Factory 创建几个类族的实例
  • Builder 将对象构造与其表示分开
  • Factory方法创建多个派生类的实例
  • 原型 要复制或克隆的完全初始化的实例
  • Singleton 一个类只能存在一个实例的类

结构模式

  • 适配器 匹配不同类的接口
  • Bridge将对象的接口与其实现分开
  • 复合 简单和复合对象的树结构
  • 装饰器 动态地向对象添加职责
  • Facade表示整个子系统的单个类
  • Flyweight 用于高效共享的细粒度实例
  • 代理 表示另一个对象的对象

行为模式

  • 响应链.一种在一组对象之间传递请求的方法
  • 命令 将命令请求封装为对象
  • 解释器 一种在程序中包含语言元素的方法
  • 迭代器 顺序访问集合的元素
  • Mediator 定义类之间的简化通信
  • Memento 捕获并恢复对象的内部状态
  • Observer 一种通知更改多个类的方法
  • 状态 更改对象在其状态更改时的行为
  • 策略 封装类中的算法
  • 模板方法将算法的确切步骤推迟到子类
  • 访客 定义一个没有更改的类的新操作

来源:dofactory