创建型-工厂模式

简单工厂模式

在程序开发中,我们经常在使用复杂对象前会进行繁琐的对象创建,但其实我们不想过多的关注对象的创建过程只想去使用它。

场景举例

假设一个果汁店有苹果汁(apple)和芒果汁(mango)两种果汁;

结构

  • 抽象产品: 定义产品规范,描述产品的主要特性和功能。
  • 具体产品:实现或继承抽象产品。
  • 具体工厂: 提供创建产品的方法,调用者通过该方法创建产品。

实现

类图如下:
在这里插入图片描述

抽象产品 果汁

/**
 * 果汁
 */
public abstract class FruitJuice {
    abstract String getName();
}

具体产品

/**
 * 苹果汁
 */
public class AppleJuice extends FruitJuice{
    @Override
    public String getName() {
        return "苹果汁";
    }
}
/**
 * 芒果汁
 */
public class MangoJuice extends FruitJuice{
    @Override
    public String getName() {
        return "芒果汁";
    }
}

工厂

/**
 * 果汁简单工厂
 */
public class FruitJuiceSimpleFactory {

    /**
     * 创建果汁
     * @param type
     * @return
     */
    FruitJuice createFruitJuice(String type) {
    // 模拟复杂对象的创建
        if ("apple".equals(type)) {
            return new AppleJuice();
        } else if ("mango".equals(type)) {
            return new MangoJuice();
        } else {
            throw new UnsupportedOperationException("暂不支持该类型!");
        }
    }
}

果汁店

/**
 * 客户端
 */
public class JucieStoreMain {

    public static void main(String[] args) {
        FruitJuiceSimpleFactory fruitJuiceSimpleFactory = new FruitJuiceSimpleFactory();
        FruitJuice fruitJuice = fruitJuiceSimpleFactory.createFruitJuice("apple");
        System.out.println("生产:" + fruitJuice.getName());
    }
}

适用场景

  • 产品种类少并且产品种类相对固定变化性不大

总结

  • 完成了客户端与对象创建过程的解耦,客户端在使用时不需要过多关注对象的创建。
  • 后期如果新增产品,需要修改工厂类中的方法,违反了“开闭原则”。

工厂方法模式

针对简单工厂中的缺点进行优化

结构

  • 抽象产品:定义产品规范,描述产品的主要特性和功能。
  • 具体产品:抽象产品的实现。
  • 抽象工厂:提供创建产品的接口,调用者通过访问具体工厂的工厂方法来创建产品。
  • 具体工厂:实现抽象工厂中的抽象方法,完成具体的产品创建。

实现

抽象产品 果汁

/**
 * 果汁
 */
public abstract class FruitJuice {
    abstract String getName();
}

具体产品

/**
 * 苹果汁
 */
public class AppleJuice extends FruitJuice{
    @Override
    public String getName() {
        return "苹果汁";
    }
}
/**
 * 芒果汁
 */
public class MangoJuice extends FruitJuice{
    @Override
    public String getName() {
        return "芒果汁";
    }
}

抽象工厂

/**
*
 */
public interface FruitJuiceFactory {
    public FruitJuice createFruitJuice();
}

具体工厂

/**
 * 苹果汁工厂
 */
public class ApplieJuiceFactory implements FruitJuiceFactory {
    @Override
    public FruitJuice createFruitJuice() {
        return new AppleJuice();
    }
}
/**
 * 芒果汁工厂
 * @author yanhaodong
 * @data 2024/5/18
 */
public class MangoJuiceFactory implements FruitJuiceFactory{
    @Override
    public FruitJuice createFruitJuice() {
        return new MangoJuice();
    }
}

客户端

public class FactoryMethodMain {
    public static void main(String[] args) {
        FruitJuiceFactory applieJuiceFactory = new ApplieJuiceFactory();
        FruitJuice fruitJuice = applieJuiceFactory.createFruitJuice();
        System.out.println("生产" + fruitJuice.getName());

        FruitJuiceFactory mangoJuiceFactory = new MangoJuiceFactory();
        FruitJuice fruitJuice1 = mangoJuiceFactory.createFruitJuice();
        System.out.println("生产" + fruitJuice1.getName());
    }
}

适用场景

  • 对象创建过程相对复杂
  • 只创建一种产品

总结

将对象的创建过程封装到各个具体的工厂实现类中,具备单一职责原则,后期出现一个新产品时只需要添加新的工厂类和产品类就可以,也满足开闭原则。但如果产品过多,就会导致类爆炸。

抽象工厂模式

场景举例

针对上述场景补充需求: 现在需要根据品牌的不同,生产对应品牌下的果汁。比如蜜雪生产的是蜜雪苹果汁,蜜雪芒果汁;喜茶生产的是喜茶苹果汁,喜茶芒果汁。

结构

  • 抽象产品:定义产品规范,描述产品的主要特性和功能。
  • 具体产品:抽象产品的实现。
  • 抽象工厂:提供创建产品的接口,调用者通过访问具体工厂的工厂方法来创建产品。
  • 具体工厂:实现抽象工厂中的抽象方法,完成具体的产品创建。

实现

抽象类

/**
 * 抽象工厂
 */
public interface AbstractFruitFactory {

    /**
     * 生产果汁
     * @return
     */
    FruitJuice createFruitJuice();

    /**
     * 生产奶茶
     * @return
     */
    MilkTea createMilkTea();
}

/**
 * 果汁
 */
public abstract class FruitJuice {
    public abstract String getName();
}


/**
 * 奶茶
 */
public abstract class MilkTea {
    public abstract String getName();
}

蜜雪具体实现类

/**
 * 蜜雪果汁
 */
public class MiXueFruitJuice extends FruitJuice {
    @Override
    public String getName() {
        return "蜜雪果汁";
    }
}

/**
 * 蜜雪奶茶
 */
public class MiXueMilkTea extends MilkTea {
    @Override
    public String getName() {
        return "蜜雪奶茶";
    }
}

/**
 * 蜜雪工厂
 */
public class MiXueFactory implements AbstractFruitFactory{

    @Override
    public FruitJuice createFruitJuice() {
        return new MiXueFruitJuice();
    }

    @Override
    public MilkTea createMilkTea() {
        return new MiXueMilkTea();
    }
}

喜茶具体实现

/**
 *喜茶果汁
 */
public class XiChaFruitJuice extends FruitJuice {
    @Override
    public String getName() {
        return "喜茶果汁";
    }
}

/**
 * 喜茶奶茶
 */
public class XiChaMilkTea extends MilkTea {
    @Override
    public String getName() {
        return "喜茶奶茶";
    }
}

/**
 * 喜茶工厂
 */
public class XiChaFactory implements AbstractFruitFactory{

    @Override
    public FruitJuice createFruitJuice() {
        return new XiChaFruitJuice();
    }

    @Override
    public MilkTea createMilkTea() {
        return new XiChaMilkTea();
    }
}

客户端

public class AbstractFactoryMain {
    public static void main(String[] args) {
        AbstractFruitFactory fruitFactory = new MiXueFactory();
        FruitJuice appleJuice = fruitFactory.createFruitJuice();
        MilkTea mangoJuice = fruitFactory.createMilkTea();

        AbstractFruitFactory fruitFactory1 = new XiChaFactory();
        FruitJuice appleJuice1 = fruitFactory1.createFruitJuice();
        MilkTea mangoJuice1 = fruitFactory1.createMilkTea();
    }
}

适用场景

  • 对象创建过程相对复杂
  • 针对一系列产品族的创建

总结

抽象工厂和工厂方法模式对比起来差别不大,唯一的区别是工厂方法的工厂只创建一类产品,而抽象工厂中的工厂可以创建多类产品。多类产品中它强调的是生态或者产品族。

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值