工厂模式

三种工厂有各自使用的场景, 任意一方都不能完全替代另一个。

简单工厂

根据枚举值来创建并返回对象,缺点就是每新增一种产品类型,就要维护这个类。这个工厂只有一个类,且只有一个简单的方法,所以叫简单工厂:

public class SimpleFactory {
    public static Product makeProduct(int kind) {
        switch (kind) {
            case Const.PRODUCT_A:
                return new ConcreteProductA();
            case Const.PRODUCT_B:
                return new ConcreteProductB();
        } 
        return null;
    }
}

工厂方法

简单工厂在添加新的产品时,仍然需要修改工厂代码,这不符合开闭原则。而工厂方法定义了一个用于创建对象的接口,让子类决定实例化哪个产品类对象。工厂方法模式让一个产品类的实例化延迟到其工厂的子类:

工厂方法共有四个角色:

  1. 抽象工厂

  2. 具体工厂,每个具体工厂生产一种具体的产品

  3. 抽象产品

  4. 具体产品

// 抽象工厂
public interface FreeGoodsFactory {
    IFreeGoods getInstance();
}
// 具体的工厂
public class DiscountFreeGoodsFactory implements FreeGoodsFactory {

    @Override
    public IFreeGoods getInstance() {
        return new DiscountFreeGoods();
    }
}
public class SmallGiftFreeGoodsFactory implements FreeGoodsFactory {
    @Override
    public IFreeGoods getInstance() {

        return new SmallGiftFreeGoods();
    }
}
// 使用工厂方法
/**
 * 按照类型的不同发放商品
 */
public ResponseResult awardToUser(AwardInfo awardInfo){

    FreeGoodsFactory freeGoodsFactory = null;

    if(awardInfo.getAwardType() == 1){
        freeGoodsFactory = new DiscountFreeGoodsFactory();
    }else if(awardInfo.getAwardType() == 2){
        freeGoodsFactory = new SmallGiftFreeGoodsFactory();
    }

    IFreeGoods freeGoods = freeGoodsFactory.getInstance();
    ResponseResult result = freeGoods.sendFreeGoods(awardInfo);
    return result;
}

工厂方法仍然耦合了获取工厂的代码,如果需要解耦这个获取工厂的方法,可以

  1. 使用工厂模式创建工厂再次包裹。

  2. 使用享元模式将单例工厂放入池中,通过key取出。

抽象工厂

工厂方法模式只可以创建一类产品(电视机类,海尔电视机、海信电视机、TCL电视机),而抽象工厂则是创建一个产品族(海尔电视、海尔冰箱、海尔洗衣机,都是海尔一族;海信电视、海信冰箱、海信洗衣机都是海信一族...)。

代码如下:

抽象工厂

/**
 * 抽象工厂: 在一个抽象工厂中可以声明多个工厂方法,用于创建不同类型的产品
 * @author spikeCong
 * @date 2022/9/15
 **/
public interface AppliancesFactory {

    AbstractTV createTV();

    AbstractFreezer createFreezer();
}

具体工厂: 每一个具体工厂方法,可以返回一个特定的产品对象,而同一个具体工厂所创建的产品对象构成了一个产品族.

public class HairFactory implements AppliancesFactory {

    @Override
    public AbstractTV createTV() {
        return new HairTV();
    }

    @Override
    public AbstractFreezer createFreezer() {
        return new HairFreezer();
    }
}

public class HisenseFactory implements AppliancesFactory {

    @Override
    public AbstractTV createTV() {
        return new HisenseTV();
    }

    @Override
    public AbstractFreezer createFreezer() {
        return new HisenseFreezer();
    }
}

抽象产品

public interface AbstractFreezer {}
public interface AbstractTV {}

具体产品

public class HairFreezer implements AbstractFreezer {}
public class HisenseFreezer implements AbstractFreezer {}
public class HairTV implements AbstractTV {}
public class HisenseTV implements AbstractTV {}

客户端

public class Client {

    private AbstractTV tv;

    private AbstractFreezer freezer;

    public Client(AppliancesFactory factory){

        //在客户端看来就是使用抽象工厂来生产家电
        this.tv = factory.createTV();
        this.freezer = factory.createFreezer();
    }

    public AbstractTV getTv() {
        return tv;
    }

    public void setTv(AbstractTV tv) {
        this.tv = tv;
    }

    public AbstractFreezer getFreezer() {
        return freezer;
    }

    public void setFreezer(AbstractFreezer freezer) {
        this.freezer = freezer;
    }

    public static void main(String[] args) {

        Client client = new Client(new HisenseFactory());
        AbstractTV tv = client.getTv();
        System.out.println(tv);

        AbstractFreezer freezer = client.getFreezer();
        System.out.println(freezer);
    }
}

最后更新于