设计模式----工厂模式

简单工厂模式:

当代吗使用具体类时,一旦加入新的具体类,就必须要改变代码(import该类)。我们希望在生成对象的时候,不使用new+具体类的名称,而是希望调用一个简单的方法,传递一个参数过去,就可以返回一个具体的对象。通过这种方法,我们减少了我们对其他代码的类的名称的依赖。

简单例子的类图如下
这里写图片描述
如图所示,相比于原来,如果要提供四种pizza对象,用户需要知道内部四个类的名称进行创建,如果类的名称修改,客户的程序将无法运行正常。而采取简单工厂模式的耦合只有一个方法。

工厂方法模式:

又称之为虚拟构造器,父类负责定义创建类的公共接口,子类负责生成具体对象。
以上述例子为例,制作pizza对象只有simplypizzafactory负责。但是如果要实现制作pizza对象的的不同流程,就需要新增工厂。
假设用户在上面的例子中需要新加对象的产生流程,在不修改源代码的情况下,可以在原来的代码中添加新的工厂。这便是工厂方法模式。
这里写图片描述
注意,用户如果想要生成pizza对象,需要先生成工厂对象,再按照工厂对象所遵循的抽象接口生成pizza对象。所以耦合度为工厂的类的名称和工厂所遵循的抽象接口。

抽象工厂模式

如果在工厂模式下,需要添加一种新的抽象产品,比如说除了pizza还要售卖Hotdog,工厂方法仍然避免如果完全新增一种抽象产品的修改。所以采用抽象工厂法
继承于同一个抽象产品的被称之为产品等级结构,由同一个抽象工厂生产的产品被称之为产品族。如果每个产品族只有一个产品,则退回到工厂方法
这里写图片描述

应用

  1. 防范在构造对象过程中this引用从本线程中逸出。
    不要在构造函数中将被对象的this的引用显示或者隐式的泄露出去(就是保证在构造完成保证this对象不被非构造线程可见)
public class ThisEscape {
      public final int id;
      public final String name;
      public ThisEscape(EventSource<EventListener> source) {//此时,外部线程就可以通过其持有的souce引用访问这个对象了。而此时,对象的构造还没有完成
            id = 1;
            source.registerListener(new EventListener() {
                  public void onEvent(Object obj) {
                        System.out.println("id: "+ThisEscape.this.id);
                        System.out.println("name: "+ThisEscape.this.name);
                  }
            });
            name = "flysqrlboy";
            
      }
  }

上述代码应该更改为工厂方法

public class ThisSafe {
 
      public final int id;
      public final String name;
      private final EventListener listener;
      
      private ThisSafe() {
            id = 1;
            listener = new EventListener(){
                  public void onEvent(Object obj) {
                        System.out.println("id: "+ThisSafe.this.id);
                        System.out.println("name: "+ThisSafe.this.name);
                  }
            };
            name = "flysqrlboy";
      }
      //采取工厂方法
      public static ThisSafe getInstance(EventSource<EventListener> source) {
            ThisSafe safe = new ThisSafe();
            source.registerListener(safe.listener);
            return safe;
      }    
}

另外,基于同样的原因,我们不能在构造函数中启动线程,所以,我们需要工厂方法来启动线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值