2 创建型模式之 - 工厂模式
九路 495 11

工厂模式适用于大量产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建。我不喜欢看一堆的理论,书上把工厂模式分为下面三种。

1 简单工厂模式

2 工厂方法模式

3 抽象工厂模式

一 简单工厂模式

先看第1种,简单工厂模式,所谓简单,就是直接能想到的,直接 if 判断,符合条件就创建相应的对象,我们以生产不同的手机为例子。分别生产小米手机,Nokia手机,三星手机,代码如下:

 //手机
 public interface Phone {
     void call();
 }
//Nokia手机
public class NokiaPhone implements Phone {
    @Override
    public void call() {
        System.out.println("我用诺基亚手机打电话");
    }
}
//三星手机
public class SanuagPhone implements Phone {
    @Override
    public void call() {
        System.out.println("我用三星手机打电话");
    }
}
//小米手机
public class XiaoMiPhone implements Phone {
    @Override
    public void call() {
        System.out.println("我用小米手机打电话");
    }
}
/**
 *
 * 简单工厂模式
 * 工厂里面有一个生产手机的方法,根据不同的值生产不同的手机
 *
 */
public class PhoneFactory {

    public Phone produce(String type){
        Phone phone = null;

        if("xiaomi".equals(type)){
            phone = new XiaoMiPhone();
        }else if("sanuag".equals(type)){
            phone = new SanuagPhone();
        }else if("nokia".equals(type)){
            phone = new NokiaPhone();
        }

        return phone;
    }

}

特点:生产少量产品,可以用这种方法,生产大量的产品需要修改原来的代码,而且传入的参数有可能会出错,所以适用条件是生产少量的产品,下面看看工厂方法模式

二 工厂方法模式

为什么叫工厂方法模式,关键在于“方法”,因为工厂方法模式中,工厂类中有许多的方法用来生产不同的手机,不同于简单工作模式(工厂中只有一个生产方法),工厂方法模式中,工厂类中有许多的方法用来生产不同的产品的,代码如下

/**
 *
 * 工厂类中有许多的方法用来生产不同的产品的
 *
 * 是对简单工厂方法模式的改进,
 * 在简单工厂方法模式中,如果传递的字符串出错,则不能正确创建对象,
 * 而多个工厂方法模式是提供多个工厂方法,分别创建对象
 *
 */
public class PhoneFactory2 {
    public Phone produceNokia(){
        return new NokiaPhone();
    }

    public Phone produceXiaomi(){
        return new XiaoMiPhone();
    }

    public Phone produceSanug(){
        return new SanuagPhone();
    }

}

工作方法解决了第一种简单工厂模式中,字符串传入出错会出现创建不了对象的情况,而且也能解决创建少量对象的问题,不过也不能创建太多的对象,但相对于简单工厂模式,要好多了,不过PhoneFactory2 类还是可以再优化的,可以把类中的方法都改成静态的,这样就可以不用创建工厂对象就可以创建对象了,代码如下:

/**
 * 将上面的多个工厂方法模式里的方法置为静态的,不需要创建实例,直接调用即可。
 *
 * 简单工厂模式 之静态工厂方法模式。
 *
 * 总体来说,工厂模式适合:凡是出现了大量的产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建。
 * 在以上的三种模式中,第一种如果传入的字符串有误,不能正确创建对象,第三种相对于第二种,不需要实例化工厂类,
 * 所以,大多数情况下,我们会选用第三种——静态工厂方法模式。
 */
public class PhoneFactory3 {
    private PhoneFactory3(){}

    public static Phone produceNokia(){
        return new NokiaPhone();
    }

    public static Phone produceSanug(){
        return new SanuagPhone();
    }

    public static Phone produceXiaomi(){
        return new XiaoMiPhone();
    }

}

三 抽象工厂模式

抽象工厂为什么叫抽象工厂?自己的理解就是因为抽象工厂代码中的工厂是抽象的,所以叫做抽象工厂,上面2种工厂模式,不管是简单工厂模式还是工厂方法模式或者是工厂方法模式中的优化的方案,都有一个缺点,在创建大量对象的时候,都需要对原来的代码进行修改才能达到扩展的目的,因为都是一个工厂生产多种产品,是一对多的。那么可不可以多对多呢,就是多个工厂生产各自的产品。对于本例就是三星的工厂只生产三星的手机,小米的工厂只生产小米的手机,这样的话,如果需要再添加需求,比如还要生产华为的手机,那么可以直接添加一个华为的工厂,直接生产华为手机就是了,不用修改原来的代码,这样可以做到对修改关闭,对扩展开放(见设计模式之六大原则之开闭原则),代码如下:

public interface Factory {
     Phone produce();
 }
//生产小米手机的工厂
public class NokiaFactory implements Factory{
    @Override
    public Phone produce() {
        return new NokiaPhone();
    }
}
//生产三星手机的工厂
public class SanuagFactory implements Factory{
    @Override
    public Phone produce() {
        return new SanuagPhone();
    }
}
//生产小米手机的工厂
public class XiaomiFactory implements Factory{
    @Override
    public Phone produce() {
        return new XiaoMiPhone();
    }
}
  private static void testFactoryMethod(){
         Factory factory = new NokiaFactory();
         Phone phone = factory.produce();
         phone.call();
  }

这样就可以做到了对扩展开放对修改关闭,工厂和产品都是抽象的,依赖接口,面向接口编程。

可以达到更好的扩展性,上面的几个例子希望能帮忙读者理解工厂模式。本文的代码放到了github上

git@github.com:jiulu313/DesignSchema.git

评论区

索引目录