设计模式-工厂模式和抽象工厂-Factory

本文讲解GOF-23种设计模式其中的工厂方法模式抽象工厂模式
由于本人爱国情怀高涨,所以本文都以长安汽车作为示例,阅读本文需要对长安汽车有一定了解。
长安悦翔V7:长安旗下一款性价比超高的紧凑型家用轿车,轮胎尺寸R15。
长安CS75:长安旗下一款中端紧凑型城市SUV,轮胎尺寸R17。
以上两款车和车轮胎都是长安集团的产品,那么生产轮胎和组装车的地方是长安的工厂。

一. 简单工厂模式

1、简介

简单工厂模式(Simple Factory)其实不算是23种设计模式之一,只算是工厂方法模式的一种特殊写法,是较为常用的工厂模式(下文简称模式A)。

2、成员

抽象产品:它是具体产品的抽象父类 或者实现的接口。
具体产品:具体的产品类,在JAVA中是一个实现了抽象产品的类。
工厂类:生产具体产品的工厂,具有一定的业务逻辑和判断,生产不同的具体产品

3、使用场景

在业务简单,对象较少且不易改动的情况下可使用此模式。

4、代码示例
/**
 * 作者: Created by AdminFun
 * 邮箱: [email protected]
 * 描述: 这是一个长安汽车抽象类,用[abstract]抽象类也可实现!
 */
public interface ICar {

    /**
     * 汽车的价格
     */
    double getPrice();

    /**
     * 汽车的型号
     */
    String getModel();
}
/**
 * 作者: Created by AdminFun
 * 邮箱: [email protected]
 * 描述: 这是具体的长安汽车产品-悦翔V7,需要实现汽车接口。
 */
public class V7Info implements ICar {

    @Override
    public double getPrice() {
        return 100000;
    }

    @Override
    public String getModel() {
        return "长安悦翔V7";
    }
}
/**
 * 作者: Created by AdminFun
 * 邮箱: [email protected]
 * 描述: 这是具体的长安汽车产品-CS75,需要实现汽车接口。
 */
public class CS75Info implements ICar {

    @Override
    public double getPrice() {
        return 150000;
    }

    @Override
    public String getModel() {
        return "长安CS75";
    }
}
/**
 * 作者: Created by AdminFun
 * 邮箱: [email protected]
 * 描述: 工厂模式-简单模式
 * 解释: 这是长安汽车的工厂,可以根据不同的需求生产不同的汽车产品。
 */
public class ICarFactory_1 {

    public static final String car_type_v7 = "V7";
    public static final String car_type_cs75 = "CS75";

    public static ICar createCar(String carType) {
        if (car_type_v7.equals(carType)) {
            return new V7Info();
        } else if (car_type_cs75.equals(carType)) {
            return new CS75Info();
        } else {
            return new V7Info();
        }
    }
}
 /**
     * 测试简单工厂模式
     */
    public void TestFactory1() {
        ICar car1 = ICarFactory_1.createCar(ICarFactory_1.car_type_v7);
        Log.d("MainActivity", car1.getModel() + "的价格是" + car1.getPrice());
    }

最终打印结果:长安悦翔V7的价格是100000.0

二、工厂方法模式

1、简介

工厂方法模式(Factory Method),是为解决模式A的一些缺点而生。
(下文把此模式简称模式B)

2、优点/区别

1、解耦:消费者与产品完全隔离,消费者依赖产品接口实现对产品的操作。
2、扩展:如果要新增汽车类型,只需增加具体汽车类和工厂即可,不用修改原工厂。

3、成员:

除了模式A里面的【抽象产品】【具体产品】,还需新增以下成员:
抽象工厂:它是具体工厂的抽象父类/实现的接口。
具体工厂:此处的工厂也是模式A中的工厂,与模式A工厂的区别是:模式A的工厂可以根据逻辑判断生产不同的产品,而模式B的工厂只能生产一种产品,如果需要生产多种产品则需要创建多个工厂。

4、使用场景

如果产品类型比较单一,且不能预见需要创建哪些类、创建多少类的情况下使用模式B。

5、代码示例:(接上文的例子)
/**
 * 作者: Created by AdminFun
 * 邮箱: [email protected]
 * 描述: 工厂方法模式-长安的工厂都必须遵循此协议
 */
public interface ICarFactory_2 {
    ICar createCar();
}
/**
 * 作者: Created by AdminFun
 * 邮箱: [email protected]
 * 描述: 这是长安其中一家工厂,此工厂只生产悦翔V7
 */
public class CarV7Factory_2 implements ICarFactory_2 {

    @Override
    public ICar createCar() {
        return new V7Info();
    }
}
/**
 * 作者: Created by AdminFun
 * 邮箱: [email protected]
 * 描述: 这是长安另一家工厂,此工厂只生产CS75
 */
public class CarCS75Factory_2 implements ICarFactory_2 {

    @Override
    public ICar createCar() {
        return new CS75Info();
    }
}
     /**
     * 测试工厂方法模式
     */
    public void TestFactory2() {
        ICarFactory_2 factory_v7 = new CarV7Factory_2();
        ICar car_v7 = factory_v7.createCar();
        Log.d("MainActivity", "A:" + car_v7.getModel() + "的价格是" + car_v7.getPrice());

        ICarFactory_2 factory_CS75 = new CarCS75Factory_2();
        ICar car_75 = factory_CS75.createCar();
        Log.d("MainActivity", "B:" + car_75.getModel() + "的价格是" + car_75.getPrice());
    }

最终打印结果:
A:长安悦翔V7的价格是100000.0
B:长安CS75的价格是150000.0

三、抽象工厂模式

1、简介

抽象工厂模式(Abstract Factory)是模式B的更为抽象的写法,成员与模式B相同,就不具体列举了(以下简称模式C)。

2、代码示例(继续接上文例子,注意此例子中长安集团产品族中增加了新的产品:轮胎)
/**
 * 作者: Created by AdminFun
 * 邮箱: [email protected]
 * 描述: 这是长安轮胎产品协议,用[abstract]抽象类也可实现!
 */
public interface ITyre {

    /**
     * 轮胎尺寸
     */
    String getSize();
}
/**
 * 作者: Created by AdminFun
 * 邮箱: [email protected]
 * 描述: 长安悦翔V7的轮胎
 */
public class V7TyreInfo implements ITyre {

    @Override
    public String getSize() {
        return "R15";
    }
}
/**
 * 作者: Created by AdminFun
 * 邮箱: [email protected]
 * 描述: 长安CS75的轮胎
 */
public class CS75TyreInfo implements ITyre {

    @Override
    public String getSize() {
        return "R17";
    }
}
/**
 * 作者: Created by AdminFun
 * 邮箱: [email protected]
 * 描述: 抽象工厂模式
 * 解释: 长安新增了产品,那么工厂的协议就要改变了,既要生产汽车也要生产轮胎
 */
public interface ICarFactory_3 {

    /**
     * 生产汽车
     */
    ICar createCar();

    /**
     * 生产轮胎
     */
    ITyre createTyre();
}
/**
 * 作者: Created by AdminFun
 * 邮箱: [email protected]
 * 描述: 这是长安其中一家工厂,此工厂原来只生产悦翔V7,现在新增了轮胎生产线
 */
public class CarV7Factiry_3 implements ICarFactory_3 {

    @Override
    public ICar createCar() {
        return new V7Info();
    }

    @Override
    public ITyre createTyre() {
        return new V7TyreInfo();
    }
}
/**
 * 作者: Created by AdminFun
 * 邮箱: [email protected]
 * 描述: 这是长安另一家工厂,此工厂原来只生产CS75,现在新增了CS75轮胎的生产线
 */
public class CarCS75Factory_3 implements ICarFactory_3 {
    @Override
    public ICar createCar() {
        return new CS75Info();
    }

    @Override
    public ITyre createTyre() {
        return new CS75TyreInfo();
    }
}
 /**
     * 测试抽象工厂模式
     */
    public void TestFactoiry3() {
        ICarFactory_3 factory_v7 = new CarV7Factiry_3();
        ICar carV7 = factory_v7.createCar();
        ITyre tyrev7 = factory_v7.createTyre();
        Log.d("MainActivity", "C:" + carV7.getModel() + "的价格是" + carV7.getPrice() + ",轮胎尺寸是" + tyrev7.getSize());

        ICarFactory_3 factory_75 = new CarCS75Factory_3();
        ICar car75 = factory_75.createCar();
        ITyre tyre75 = factory_75.createTyre();
        Log.d("MainActivity", "C:" + car75.getModel() + "的价格是" + car75.getPrice() + ",轮胎尺寸是" + tyre75.getSize());
    }

最终打印结果:
C:长安悦翔V7的价格是100000.0,轮胎尺寸是R15
C:长安CS75的价格是150000.0,轮胎尺寸是R17

你可能感兴趣的:(设计模式-工厂模式和抽象工厂-Factory)