简单工厂模式
在程序开发中,我们经常在使用复杂对象前会进行繁琐的对象创建,但其实我们不想过多的关注对象的创建过程只想去使用它。
场景举例
假设一个果汁店有苹果汁(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();
}
}
适用场景
- 对象创建过程相对复杂
- 针对一系列产品族的创建
总结
抽象工厂和工厂方法模式对比起来差别不大,唯一的区别是工厂方法的工厂只创建一类产品,而抽象工厂中的工厂可以创建多类产品。多类产品中它强调的是生态或者产品族。