工厂方法和抽象工厂模式

文章目录

一、工厂方法

工厂方法定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。

1、工厂法法模式结构图:

工厂方法和抽象工厂模式
工厂方法抽象出一个工厂接口,这个接口只有一个方法,就是创建抽象产品的工厂方法,所有要生产具体类的工厂就去实现这个接口。当需要创建新对象的工厂时,就不需要更改原有的工厂类,只需要增加相应的工厂类。

产品抽象类 Product

public abstract class Product {
    protected String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

具体产品类 ConcreteProductA

public class ConcreteProductA extends Product{

    public ConcreteProductA(){
        super();
        this.name = "具体产品 A";
    }
}

具体产品类 ConcreteProductB

public class ConcreteProductB extends Product{

    public ConcreteProductB(){
        super();
        this.name = "具体产品 B";
    }
}

抽象工厂接口 Factory

public interface Factory {
    public Product createProduct();
}

创建 ConcreteProductA 的工厂类 ConcreteProductAFactory

public class ConcreteProductAFactory implements Factory{
    @Override
    public Product createProduct() {
        return new ConcreteProductA();
    }
}

创建 ConcreteProductB 的工厂类 ConcreteProductBFactory

public class ConcreteProductBFactory implements Factory{
    @Override
    public Product createProduct() {
        return new ConcreteProductB();
    }
}

效果测试类

public class FactoryMethodTest {
    public static void main(String[] args) {
        Factory factoryA = new ConcreteProductAFactory();
        Factory factoryB = new ConcreteProductBFactory();
        Product productA = factoryA.createProduct();
        Product productB = factoryB.createProduct();

        System.out.println(productA.getName());
        System.out.println(productB.getName());
    }
}

2、工厂方法模式的优缺点

工厂方法模式具有良好的封装性,代码结构清晰。如果一个调用者需要一个具体的产品对象,只要知道这个产品的类名,不用知道创建对象的艰辛过程,降低模块间的耦合,并且拓展性好。但缺点也是相对的,每增加一个产品,就需要加一个产品的工厂类,增加了额外的开发量。

二、抽象工厂模式

抽象工厂模式定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

1、抽象工厂模式结构图

工厂方法和抽象工厂模式
AbstractProductA 和 AbstractProductB 是两个抽象产品,而ProductA1和ProductA2、ProductB1、ProductB2就是对两个抽象产品的具体实现。

AbstractFactory是一个抽象工厂接口,它里面包含所有产品创建的抽象方法。而ConcreteFactory1 和ConcreteFactory2就是具体的工厂了。

抽象产品类 AbstractProductA

public abstract class AbstractProductA {
    protected String type = "A型产品";

    protected String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    /** 每个产品具体实现该方法 */
    public abstract void doSomething();
}

抽象产品类 AbstractProductB

public abstract class AbstractProductB {
    protected String type = "B型产品";

    protected String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    /** 每个产品具体实现该方法 */
    public abstract void doSomething();
}

A型具体产品 ProductA1

public class ProductA1 extends AbstractProductA{

    public ProductA1(){
        super();
        this.name = "产品A1";
    }
    @Override
    public void doSomething() {
        System.out.println(this.name + " doSomething");
    }
}

A型具体产品 ProductA2

public class ProductA2 extends AbstractProductA{

    public ProductA2(){
        super();
        this.name = "产品A2";
    }
    @Override
    public void doSomething() {
        System.out.println(this.name + " doSomething");
    }
}

B型具体产品 ProductB1

public class ProductB1 extends AbstractProductB{

    public ProductB1(){
        super();
        this.name = "产品B1";
    }
    @Override
    public void doSomething() {
        System.out.println(this.name + " doSomething");
    }
}

B型具体产品 ProductB2

public class ProductB2 extends AbstractProductB{

    public ProductB2(){
        super();
        this.name = "产品B2";
    }
    @Override
    public void doSomething() {
        System.out.println(this.name + " doSomething");
    }
}

抽象工厂接口 AbstractFactory

public interface AbstractFactory {

    public AbstractProductA createProductA();

    public AbstractProductB createProductB();
}

创建1系列产品的工厂类 ConcreteFactory1

public class ConcreteFactory1 implements AbstractFactory{
    @Override
    public AbstractProductA createProductA() {
        return new ProductA1();
    }

    @Override
    public AbstractProductB createProductB() {
        return new ProductB1();
    }
}

创建2系列产品的工厂类 ConcreteFactory2

public class ConcreteFactory2 implements AbstractFactory{
    @Override
    public AbstractProductA createProductA() {
        return new ProductA2();
    }

    @Override
    public AbstractProductB createProductB() {
        return new ProductB2();
    }
}

效果测试类

public class AbstractFactoryTest {
    public static void main(String[] args) {
        AbstractFactory factory = new ConcreteFactory1();

        AbstractProductA productA = factory.createProductA();
        AbstractProductB productB = factory.createProductB();
        productA.doSomething();
        productB.doSomething();

        System.out.println("=========切换产品系列工厂=========");

        factory = new ConcreteFactory2();
        productA = factory.createProductA();
        productB = factory.createProductB();
        productA.doSomething();
        productB.doSomething();
    }

}

输出:
产品A1 doSomething
产品B1 doSomething
=切换产品系列工厂=
产品A2 doSomething
产品B2 doSomething

由此可见,切换工厂类,即可对获取的产品系列进行切换

2、抽象工厂模式的优缺点

抽象工厂最大的好处是便于切换产品系列,其次是它让具体的创建实例过程与客户端分离,客户端是通过抽象接口获取实例,依赖的产品也是抽象的,而不是具体的产品类。

抽象工厂的缺点是产品族的拓展非常困难,如果增加了一个产品,抽象工厂类中需要增加创建该产品的抽象方法,具体工厂类中也得去实现,涉及到的改动多。

上一篇:Effective C++ 条款17:以独立的语句将new出的对象置入智能指针


下一篇:设计模式-模板模式