工厂模式(Factory Pattern):
在工厂模式中,这3个名词容易被混淆:简单工厂模式,工厂方法模式,抽象工厂模式。
简单工厂模式:
- 将变化部分抽出,保存在新的对象中,这个负责生产的对象即工厂。
- 简单工厂模式其实不是一个设计模式,更像是一种编程习惯。
工厂方法模式:例子:
1、工厂客户(披萨店):
public class PizzaShop { SimplePizzaFactory factory; public PizzaShop(SimplePizzaFactory factory){ this.factory = factory; } Pizza orderPizza(String type){ Pizza pizza; pizza = factory.createPizza(type); pizza.prepare(); pizza.bake(); ... return pizza; } }
2:工厂
public class PizzaShop { SimplePizzaFactory factory; public PizzaShop(SimplePizzaFactory factory){ this.factory = factory; } Pizza orderPizza(String type){ Pizza pizza; pizza = factory.createPizza(type); pizza.prepare(); pizza.bake(); ... return pizza; } }
3,示例图:
定义:
定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
功能:
通过工厂模式,我们的代码完全与实现分离,既可动态,透明的将某个实现替换为另一个实现。
例子:
创建者类:
public abstract class PizzaShop { Pizza orderPizza(String type){ Pizza pizza; pizza = createPizza(type); pizza.prepare(); pizza.bake(); ... return pizza; } protected abstract Pizza createPizza(String type); }
创建者实现:
public class ChicagoPizzaStore extends PizzaShop { @Override protected Pizza createPizza(String type) { Pizza pizza; ... return pizza; } }
public class NYPizzaStore extends PizzaShop { @Override protected Pizza createPizza(String type) { Pizza pizza; ... return pizza; } }
产品类:
public abstract class Pizza { String name; String dough; void prepare(){ ...; } void bake(){ } ... }
产品类实现:public class NYStyleCheesePizza extends Pizza { public NYStyleCheesePizza(){ name = "NYStyle"; } }
public class ChicagoStyleCheesePizza extends Pizza { public ChicagoStyleCheesePizza(){ name = "Chicago Style"; } void cut(){ // Chicago style cut } }
抽象工厂模式
定义:
提供一个借口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
例子:
工厂对象接口:
public interface Cycle {
void ride();
}
工厂接口:
public interface CycleFactory {
Cycle getCycle();
}
实现类:这里例子是双轮车与单轮车,双轮车:
public class Bicycle implements Cycle {
public void ride() {
System.out.println("Bicycle is riding!");
}
}
public class BicycleFactory implements CycleFactory {
public Cycle getCycle() {
return new Bicycle();
}
}
单轮车:
public class Unicycle implements Cycle {
public void ride() {
System.out.println("Unicycle is riding !");
}
}
public class UnicycleFactory implements CycleFactory{
public Cycle getCycle() {
return new Unicycle();
}
}
主函数:
public class main {
static void run(CycleFactory factory){
factory.getCycle().ride();
}
public static void main(String args[]){
run(new BicycleFactory());
run(new UnicycleFactory());
run(new TricycleFactory());
}
}
优点:
- 能从具体的产品中被解耦。
- 可以把一群相关的产品集合起来。
缺点:
- 如果扩展这组产品,就需要改变接口,导致大量的修改。
总结:
对于创建类,任何时候都可以替代为创建一个借口和一个工厂。但如果为了抽象而抽象,那实际上是一种草率的设计优化。
任何抽象性都应该是应真正需求而产生的。当必须时,应该重构接口而不是到处添加额外的间接性,并由此带来额外的复杂性。
恰当的原则应该优先选择类而不是接口。
从类开始,如果接口的必须行变得非常明确,那么就进行重构。接口是一种重要的工具,但是他们容易被滥用。