工厂解决的问题
- 客户端在调用是不想判断实例化哪一个类或者实例化的过程过于复杂。
- 在工厂模式中,具体的实现类创建过程对客户端是透明的,客户端不决定具体实例化哪一个类,而是交由“工厂”来实例化。
简单工厂模式
类图
简单工厂模式由三类角色组成:
- 抽象产品(Pizza)
- 具体产品(CheesePizza、VeggiePizza、ClamPizza)
- 工厂类(SimplePizzaFactory)
客户端代码(PizzaStore)
pulic class PizzaStore{
//添加工厂的引用
SimplePizzaFactory factory;
public PizzaStore(SimplePizzaFactory factory){
this.factory = factory;
}
//披萨来自于工厂
Pizza pizza = factory.createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
简单工厂代码(SimplePizzaFactory)
public class SimplePizzaFactory(){
Pizza orderPizza(String type){
Pizza pizza;
if("cheese".equals(type)){
pizza = new CheesePizza();
}else if("greek".equals(type)){
pizza = new GreekPizza;
}
return pizza;
}
}
public class SimplePizzaFactory(){
//静态方法
static Pizza orderPizza(String type){
Pizza pizza;
if("cheese".equals(type)){
pizza = new CheesePizza();
}else if("greek".equals(type)){
pizza = new GreekPizza;
}
return pizza;
}
}
特点
- 简单工厂类是一个具体的类,非接口抽象类。
- 简单工厂类中具有一个重要的创建方法(orderPizza),利用if或者switch创建产品并返回。
- 创建方法也可以设置为静态方法,所以也可以称之为***静态工厂方法***。
缺点
- 扩展性差,不符合“开闭原则”,如果想要增加一种产品(比萨),需要修改工厂方法代码。
- 依赖参数(type)生产不同的产品。
工厂方法模式
定义
工厂方法模式:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
类图
创建者(工厂)
产品
工厂方法模式
工厂方法模式由四类角色组成:
- 抽象产品(Product)
- 具体产品(ConcreteCreator)
- 抽象工厂(Creator)
- 具体工厂(ConcreteCreator)
工厂模式代码实现
产品类
抽象产品类
public abstract class Pizza {
String name;
String dough;
String sauce;
ArrayList toppings = new ArrayList();
void prepare(){
System.out.println("Preparing "+name);
System.out.println("Tossing dough...");
System.out.println("Adding sauce...");
System.out.println("Adding toppings: ");
for(int i = 0;i<toppings.size();i++){
System.out.println(" "+toppings.get(i));
}
}
void bake(){
System.out.println("Bake for 25 minutes at 350");
}
void cut(){
System.out.println("Cutting the pizza into diagonal slices");
}
void box(){
System.out.println("Place pizza in official PizzaStore box");
}
public String getName(){
return name;
}
}
具体产品类(芝加哥风味)
public class ChicagoStyleCheesePizza extends Pizza {
public ChicagoStyleCheesePizza(){
name = "Chicago Style Deep Dish Cheese Pizza";
dough = "Extra Thick Crust Dough";
sauce = "Plum Tomato Sauce";
toppings.add("Shredded Mozzarella Cheese");
}
@Override
void cut(){
System.out.println("Cutting the pizza into square slices");
}
}
具体产品类(纽约风味)
public class NYStyleCheesePizza extends Pizza {
public NYStyleCheesePizza(){
name = "NY Style Sauce and Cheese Pizza";
dough = "Thin Crest Dough";
sauce = "Marinara Sauce";
toppings.add("Grated Reggiano Cheese");
}
}
工厂类
抽象工厂类
public abstract class PizzaStore{
public Pizza orderPizza(){
Pizza pizza;
pizza = createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
//现在把工厂对象移动到这个方法中
abstract Pizza createPizza();
}
具体工厂类(纽约披萨工厂)
public class NYStylePizzaStore extends PizzaStore{
@Override
Pizza createPizza(){
return new NYStyleCheesePizza();
}
}
具体工厂类(芝加哥披萨工厂)
public class ChicagoStyleCheeseStore extends PizzaStore{
@Override
Pizza createPizza(){
return new ChicagoStyleCheesePizza();
}
}
客户端代码
//纽约风味
NYPizzaFactory nyFactory = new NYPizzaFactory();
PizzaStore nyStore = new PizzaStore(nyFactory);
nyStore.orderPizza();
//芝加哥风味
ChicagoPizzaFactory chicagoFactory = new ChicagoPizzaFactory();
PizzaStore nyStore = new PizzaStore(chicagoFactory);
nyStore.orderPizza();
特点
- 解耦:创建者和产品实现类解耦,只依赖产品接口/抽象类(抽象产品),产品实现改动与创建者完全无关。
- 加入“开闭原则”(软件实体类、模块或者函数等等,应该可以扩展,但是不可以修改)。
- 将简单工厂的内部逻辑判断,移动到了客户端,在扩展新功能,简单工厂模式需要修改工厂类,工厂方法模式只需要修改客户端。