设计模式 简单工厂 工厂 抽象工厂

1 简单工厂模式

image

1.1 定义

简单工厂模式又叫静态工厂模式,但不属于23种设计模式之一。

简单来说就是有一个类,提供一个创建方法createProduct,根据接收到的值决定实例化哪个类,但是这个简单工厂类能实例化的类必须都是同一个抽象类下的子类

image

1.2 实际应用场景

在JDK的类库中广泛使用了这个模式,比如DateFormat,可以看到根据传入的参数不同,返回不同DateFormat类的子类

image

1.3 手动实现

为了便于学习,代码都写在一个文件下

public class SimpleFactory {

    /**
     * 提供一个createProduct方法,根据传入的参数决定要创建哪个类的对象
     * @param type
     * @return
     */
    public static Product createProduct(String type) {
        if ("A".equals(type)) {
            return new ProductA();
        } else {
            return new ProductB();
        }
    }

    public static void main(String[] args) {
        Product product = SimpleFactory.createProduct("A");
        product.print();
    }

}
    /**
     * 创建一个抽象类 声明一个抽象方法
     */
    abstract class Product{
        public abstract void print();
    }

    /**
     * 创建抽象类的子类A 实现抽象方法
     */
    class ProductA extends Product{

        @Override
        public void print() {
            System.out.println("产品A创建了");
        }
    }

    /**
     * 创建抽象类的子类B 实现抽象方法
     */
    class ProductB extends Product{

        @Override
        public void print() {
            System.out.println("产品B创建了");
        }
    }


1.4 优缺点

  • 拓展:开闭原则

    程序对于拓展是开放的,对于修改是封闭的,核心观点:拓展优于修改

优点:实现了对象的创建和使用的分离,创建完全交给专门的工厂类负责,客户端程序员无需关心对象如何创建,只需要关心怎么使用

缺点:简单工厂模式不够灵活,每次新增产品类就要修改工厂类的判断逻辑,如果产品类很多,这个逻辑就会很复杂,同时修改工厂类违反了开闭原则

2 工厂模式

image

2.1 定义

简单来说就是只定义一个工厂类接口,再实现接口得到不同的子工厂类,让子工厂类分别负责不同的产品类的创建,而这些产品类依然属于同一个接口下不同的实现类

image

2.2 对比简单工厂模式

简单工厂模式

创建一个工厂类,每当新增一个产品类时就要修改工厂类

image

工厂模式

定义一个工厂接口,只给出工厂类要实现的方法,而不再负责创建对象,转而由工厂接口的各个实现类去创建对象,每当新增一个产品类时,只需要创建一个新的工厂类

image

2.3 实际应用场景

最常见的集合类Collection只是一个接口,对应着就是一个工厂接口,而具体的子类比如Arraylist,实现collection接口,就是一个实现了工厂接口的工厂类。

ArrayList能创建itr的实例,而itr是Iterator的实现类,因此整个过程就是一个工厂模式的运用。

image

类图如下

collection就是抽象工厂,具体工厂就是LinkedList,ArrayList,Iteratior就是抽象产品,具体产品就是ListItr和Itr,他们分别由LinkedList和ArrayList创建

image

2.4 手动实现

为了便于学习,将代码都放在一个文件下

public class FactoryPattern {
    public static void main(String[] args) {
        Factory factory = new ProductAFactory();
        Product product = factory.create();
        product.print();
    }
}

/**
 * 创建产品类接口
 */
interface Product{
    void print();
}

/**
 * 创建产品子类A并实现接口
 */
class ProductA implements Product{

    @Override
    public void print() {
        System.out.println("产品A被创建了");
    }
}

/**
 * 创建产品子类B并实现接口
 */
class ProductB implements Product{

    @Override
    public void print() {
        System.out.println("产品B被创建了");
    }
}

/**
 * 创建工厂接口
 */
interface Factory{
    Product create();
}

/**
 * 创建工厂子类A并生产产品子类A
 */
class ProductAFactory implements Factory{

    @Override
    public Product create() {
        return new ProductA();
    }
}

/**
 * 创建工厂子类B并生产产品子类B
 */
class ProductBFactory implements Factory{

    @Override
    public Product create() {
        return new ProductB();
    }
}

2.5 优缺点

优点:解决了简单工厂模式违反开闭原则的问题

缺点:工厂模式的每一个子工厂类只能创建固定的某个产品类,每当新增产品类时,就得新增一个子工厂类

3 抽象工厂模式

3.1 定义

简单来说就是令工厂类和产品类原本一对一的关系变成了一对多,但是如果要扩展产品类,那么还是要修改工厂接口和各个子工厂类的代码,违反开闭原则

image

3.2 对比工厂模式

  1. 抽象工厂模式解决了工厂模式的工厂类和产品类一一对应的缺点,每个工厂类可以创建其他产品类,但是抽象工厂模式的扩展性和简单工厂模式一样差,会违反开闭原则。

  2. 工厂方法模式对具体产品可扩展,抽象工厂模式对具体产品族可扩展

  3. 抽象工厂模式只是工厂模式的一个扩展,如果只有一个产品类,那么抽象工厂模式就会退化成工厂模式

image

3.3 手动实现

为了便于学习,将代码都放在一个文件下

/**
 * 抽象工厂
 */
interface AbstractFactory{
    Phone createPhone(String param);
    Mask createMask(String param);
}

/**
 * 具体工厂 可以创建产品A和B 即工厂类和产品类实现了一对多
 */
class SuperFactory implements AbstractFactory{

    @Override
    public Phone createPhone(String param) {
        if ("A".equals(param)) {
            return new iphone();
        }else{
            return new huawei();
        }
    }

    @Override
    public Mask createMask(String param) {
        if ("C".equals(param)){
            return new N95();
        }else {
            return new normal();
        }
    }
}

/**
 * 抽象产品A
 */
interface Phone{}

/**
 * 具体产品A和B
 */
class iphone implements Phone{}
class huawei implements Phone{}

/**
 * 抽象产品B
 */
interface Mask{}
/**
 * 具体产品C和D
 */
class N95 implements Mask{}
class normal implements Mask{}
posted @ 2021-10-31 19:27  夏·舍  阅读(45)  评论(0编辑  收藏  举报