§1 简单工厂模式
§1.1 角色
- 抽象产品:定义产品的规范,描述产品的主要特性和功能,如:咖啡。
- 具体产品:实现或继承抽象产品的子类,如:美式咖啡,拿铁咖啡。
- 具体工厂:提供创建产品的方式,供产品使用者调用获取具体产品,如:咖啡工厂生产咖啡,咖啡店通过咖啡工厂获取咖啡。
§1.2 点咖啡案例
- 简单工厂模式其实就是将产品的创建工作交由工厂进行,而不是让产品使用者自己去创建。
- 以点咖啡为例,咖啡店(产品使用者)不用直接去 new 咖啡(具体产品),而是通过调用咖啡工厂(具体工厂)提供的方法来获取咖啡。
§1.2.1 类图
§1.2.2 实现
public abstract class Coffee {
public abstract String getName();
public void addMilk() {
System.out.println("咖啡加奶");
}
public void addSugar() {
System.out.println("咖啡加糖");
}
}
public class AmericanCoffee extends Coffee{
@Override
public String getName() {
return "美式咖啡";
}
}
public class LatteCoffee extends Coffee{
@Override
public String getName() {
return "拿铁咖啡";
}
}
public class SimpleCoffeeFactory {
public Coffee createCoffee(String type) {
Coffee coffee = null;
if ("AmericanCoffee".equals(type)) {
coffee = new AmericanCoffee();
} else if ("LatteCoffee".equals(type)) {
coffee = new LatteCoffee();
} else {
throw new RuntimeException("该产品暂未提供");
}
return coffee;
}
}
public class CoffeeStore {
public Coffee orderCoffee(String type) {
SimpleCoffeeFactory factory = new SimpleCoffeeFactory();
Coffee coffee = factory.createCoffee(type);
coffee.addMilk();
coffee.addSugar();
return coffee;
}
}
public class Test {
public static void main(String[] args) {
CoffeeStore coffeeStore = new CoffeeStore();
Coffee coffee = coffeeStore.orderCoffee("AmericanCoffee");
System.out.println(coffee.getName());
}
}
§1.3 优点
- 与对象解耦。封装了创建对象的过程,将对象的创建与业务逻辑分离开,避免修改客户的代码。如果出现了新的咖啡品种,直接修改咖啡工厂类即可,省去对咖啡店代码的修改。
- 此时会有人疑问,既然都需要修改代码,为啥不直接修改咖啡店(产品使用者,客户)的代码呢?这是因为可能有很多咖啡店,难道每一个都要去修改一遍吗?这样是不是太麻烦了呢!
§1.4 缺点
- 虽然咖啡店(客户)代码无需修改,但是需要修改咖啡工厂(具体工厂)的代码,这样同样违反了设计原则中的开闭原则。
§2 静态工厂模式
- 静态工厂模式也不属于 23 种设计模式。
- 静态工厂模式可以说是简单工厂模式的扩展,只是将咖啡工厂(具体工厂)中创建咖啡(具体产品)的方法定义为静态方法而已。
§2.1 代码变动
public class SimpleCoffeeFactory {
public static Coffee createCoffee(String type) {
Coffee coffee = null;
if ("AmericanCoffee".equals(type)) {
coffee = new AmericanCoffee();
} else if ("LatteCoffee".equals(type)) {
coffee = new LatteCoffee();
} else {
throw new RuntimeException("该产品暂未提供");
}
return coffee;
}
}
public class CoffeeStore {
public Coffee orderCoffee(String type) {
Coffee coffee = SimpleCoffeeFactory.createCoffee(type);
coffee.addMilk();
coffee.addSugar();
return coffee;
}
}
§2.2 优点
- 咖啡店(客户)在获取咖啡(具体产品)时,不需要创建咖啡工厂(具体工厂)对象,可以直接通过类名.方法名的方式来获取,避免创建多个工厂对象导致的资源浪费。