文章目录
- 介绍
- 开始
- 架构图
- 样例一
- 定义工厂
- 定义具体工厂(上衣、下装)
- 定义产品
- 定义具体生产产品(上衣、下装)
- 测试样例
- 总结
- 优点
- 缺点
- 与抽象工厂不同点
介绍
在 Factory Method模式
中,父类决定实例的生成方式,但并不决定所要生成的具体的类,具体的处理全部交给子类负责。这样就可以将生成实例的框架(framework)和实际负责生成实例的类解耦。
开始
架构图
样例一
定义工厂
public interface Factory {
/**
* 工厂可以制作 穿搭衣服
*
* @param name 产品名称
* @return
*/
WearProduct createProduct(String name);
/**
* 获取工厂里面生成的所有产品
*
* @return
*/
List<WearProduct> getProducts();
}
定义具体工厂(上衣、下装)
@Service
@Slf4j
public class ClothesFactory implements Factory {
// 花花公子工厂,穿搭产品
private List<WearProduct> wearProducts = new ArrayList<>();
@Override
public WearProduct createProduct(String name) {
// 按照springboot的形式,这里工厂生产完产品,产品是会入库的。
// 为了快速能了解 工厂方法定义,不做过多的,展示
WearProduct wearProduct = new ClothesProduct(name);
wearProducts.add(wearProduct);
return wearProduct;
}
@Override
public List<WearProduct> getProducts() {
// 按照springboot的形式,应直接取工厂下面所有的产品。
// 为了快速能了解 工厂方法定义,这里仅将list输出
return wearProducts;
}
}
@Service
@Slf4j
public class TrousersFactory implements Factory {
// 优衣库工厂,穿搭产品
private List<WearProduct> wearProducts = new ArrayList<>();
@Override
public WearProduct createProduct(String name) {
// 按照springboot的形式,这里工厂生产完产品,产品是会入库的。
// 为了快速能了解 工厂方法定义,不做过多的,展示
WearProduct wearProduct = new TrousersProduct(name);
wearProducts.add(wearProduct);
return wearProduct;
}
@Override
public List<WearProduct> getProducts() {
// 按照springboot的形式,应直接取工厂下面所有的产品。
// 为了快速能了解 工厂方法定义,这里仅将list输出
return wearProducts;
}
}
定义产品
public interface WearProduct {
/**
* 展示产品
*/
void show();
}
定义具体生产产品(上衣、下装)
@Service
@Slf4j
@AllArgsConstructor
@NoArgsConstructor
public class ClothesProduct implements WearProduct {
private String name;
@Override
public void show() {
System.out.println("这是一个上衣:" + name);
}
}
@Service
@Slf4j
@AllArgsConstructor
@NoArgsConstructor
public class TrousersProduct implements WearProduct {
private String name;
@Override
public void show() {
System.out.println("这是一个下装:" + name);
}
}
测试样例
@Slf4j
@SpringBootTest(classes = FactoryMethodApplication.class)
public class TestFactoryMethod {
@Resource
private Map<String, Factory> factoryMap;
@Test
public void testWear() {
Factory clothesFactory = factoryMap.get("clothesFactory");
Factory trousersFactory = factoryMap.get("trousersFactory");
clothesFactory.createProduct("潇洒");
clothesFactory.createProduct("百搭");
List<WearProduct> clothesFactoryProducts = clothesFactory.getProducts();
System.out.println("-------------------上衣产品展览---------------");
for (WearProduct wearProduct : clothesFactoryProducts) {
wearProduct.show();
}
trousersFactory.createProduct("和谐");
trousersFactory.createProduct("简约");
List<WearProduct> trousersFactoryProducts = trousersFactory.getProducts();
System.out.println("-------------------下装产品展览---------------");
for (WearProduct wearProduct : trousersFactoryProducts) {
wearProduct.show();
}
}
}
总结
优点
- 符合单一职责设计原则,每个具体工厂类只负责创建对应的产品。
- 新增一种产品时,只需要增加相应的具体产品类和相应的工厂子类即可
缺点
- 添加新产品时,除了增加新产品类外,还要提供与之对应的具体工厂类,系统类的个数将成对增加,在一定程度上增加了系统的复杂度;同时,有更多的类需要编译和运行,会给系统带来一些额外的开销
- 一个具体工厂只能创建一种具体产品
与抽象工厂不同点
工厂模式
:通常有一个具体的工厂类负责创建某一类产品,客户端直接调用工厂类的方法来获取所需的产品。抽象工厂模式
:往往需要管理多个工厂,同时这多个工厂中的各个工厂,又负责创建不同的产品(零件)
。