二十三种设计模式之工厂方法
2018-02-04 本文已影响17人
夫礼者
还是觉得这个系列最难的是找到现实对应的例子,也就是如何结合实际来讲解。
1. 概述
工厂方法模式作为简单工厂模式的升级版,在原有简单工厂模式抽象层次的基础上再进一步,对工厂概念本身又作了一次抽象,将作出决定构建何种对象的时机再次后延。
2. 应用场景
现在越来越多的公司会选择为员工提供员工餐,这样会带来诸多好处例如降低成本,增加员工对公司的认同感等等。针对这个场景可以作出如下设计:
2.1 Creator
// 工厂方法, 对工厂的抽象
interface StaffMealProvider {
StaffMeal supply();
}
2.2 Product
// 工厂方法所创建的对象
interface StaffMeal {
/**
* 构成部分
* @return
*/
String getConstituent();
/**
* 制造商
* @return
*/
String getManufacturer();
}
2.3 实现
// ----------------------------------------------------- StaffMeal实现
final class AStaffMeal implements StaffMeal {
@Override
public String getConstituent() {
return "手撕鸡, 东坡肉, 小炒土豆片, 清炒小白菜, 藕汤, 米饭";
}
@Override
public String getManufacturer() {
return "A供应商";
}
}
final class BStaffMeal implements StaffMeal {
@Override
public String getConstituent() {
return "鱼香肉丝, 红烧肉, 蒸鸡蛋, 手撕包菜, 番茄鸡蛋汤, 米饭 ";
}
@Override
public String getManufacturer() {
return "B供应商";
}
}
// ----------------------------------------------------- StaffMealProvider实现
class AStaffMealProviderImpl implements StaffMealProvider {
@Override
public StaffMeal supply() {
return new AStaffMeal();
}
}
class BStaffMealProviderImpl implements StaffMealProvider {
@Override
public StaffMeal supply() {
return new BStaffMeal();
}
}
2.4 测试
final class Tester {
public static void main(String[] args) {
StaffMealProvider provider = new BStaffMealProviderImpl();
for (int i = 1; i <= 10; i++) {
StaffMeal staffMeal = provider.supply();
System.out.println(String.format("第 [ %d ] 分员工餐 : -------", i));
descriptStaffMeal(staffMeal);
}
/* 以上的测试结果
第 [ 1 ] 份员工餐 :
当前员工餐提供商为: [ B供应商 ]
员工餐构成为: [ 鱼香肉丝, 红烧肉, 蒸鸡蛋, 手撕包菜, 番茄鸡蛋汤, 米饭 ]
第 [ 2 ] 份员工餐 :
当前员工餐提供商为: [ B供应商 ]
员工餐构成为: [ 鱼香肉丝, 红烧肉, 蒸鸡蛋, 手撕包菜, 番茄鸡蛋汤, 米饭 ]
*/
}
3. 相关类图
工厂方法模式4. 结语
- 推迟做出来决定的时机,这正是本人在《软件——换个角度理解》这个系列文章里提出的唯二准则中的第二条根本准则。
- 工厂方法模式对工厂概念本身再作一次抽象,将作出决定构建何种对象的时机再次后延。
- 本人曾经总结过这样一句话: “真正做出决定的时间点和假装做出决定的时间点之间的间隔越大,系统将越灵活,越牢固。大部分系统不稳定性的重要原因之一正是作决定的时机太早,导致之后作决定时被之前作下的决定所束缚,进而处处受制”。