开头说几句 博主的博客地址:https://www.jeffcc.top/ 推荐入门学习设计模式java版本的数据Head First 《设计模式》
专业定义:工厂方法模式定义了一个创建对象的接口,但是由子类决定实例化的类是哪一个。工厂方法让实例化延迟到了子类。 博主的理解:工厂方法其实也是使用了把不变的部分和变化的部分分开封装起来的设计原则,将变化的部分提供一个抽象方法来交给子类来实现,不变的部分由工厂完成封装。 这种设计可以将对象的创建封装起来,以便得到更加松耦合,更有弹性的设计。
一家披萨店需要拓展加盟业务,届时会有许多不同地方口味的披萨出现,而我们需要做的就是设计一个工厂来让加盟商使用,具体的风味的披萨由加盟商自己决定,工厂只负责包装等内容。
package factory;
import pizza.Pizza;
/**
* 披萨工厂
*/
public abstract class PizzaStore {
public Pizza orderPizza(String type){
Pizza pizza;
// 进行创建pizza
pizza = createPizza(type);
// 下面进行的是共同的东西,所以封装起来到工厂中
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
/**
* 抽取出一个抽象的制作pizza的方法来交给子类具体实现
* 工厂模式的关键所在
* @param type 什么风味的pizza
* @return
*/
public abstract Pizza createPizza(String type);
}
package store;
import factory.PizzaStore;
import pizza.Pizza;
import pizza.impl.ChicagoStyleCheesePizza;
/**
* ChicagoPizzaStore加盟店
*/
public class ChicagoPizzaStore extends PizzaStore {
/**
* 模拟测试生产pizza 太多类型了就写一个 理论可以无限拓展
* @param type 什么风味的pizza
* @return
*/
@Override
public Pizza createPizza(String type) {
if ("cheese".equals(type)) {
return new ChicagoStyleCheesePizza();
} else {
return null;
}
}
}
package store;
import factory.PizzaStore;
import pizza.Pizza;
import pizza.impl.NYStyleCheesePizza;
/**
* 纽约pizza加盟店
*/
public class NYPizzaStore extends PizzaStore {
/**
* 模拟测试生产pizza 太多类型了就写一个 理论可以无限拓展
* @param type 什么风味的pizza
* @return
*/
@Override
public Pizza createPizza(String type) {
if ("cheese".equals(type)) {
return new NYStyleCheesePizza();
} else {
return null;
}
}
}
package pizza;
import java.util.ArrayList;
/**
* pizza的抽象类
* 也就是之前说的依赖倒置所依赖的类!!!
* 需要有pizza的操作的方法
*/
public abstract class Pizza {
public String name;//pizza名称
public String dough;//pizza面团类型
public String suace;//pizza酱料类型
public ArrayList<String> toppings = new ArrayList<>(); //佐料
/**
* 提供默认的基本做法 进行烘烤、切片、装盒 如果需要可以进行重写
*/
public void prepare() {
System.out.println("Preparing" + name);
System.out.println("Tossing dough...");
System.out.println("Adding toppings:");
toppings.forEach(topping -> {
System.out.println(" " + topping);
});
}
/**
* 烘烤
*/
public void bake() {
System.out.println("Bake for 25 minutes at 350");
}
/**
* 切片
*/
public void cut() {
System.out.println("Cutting the pizza into diagonal slices!");
}
/**
* 装盒
*/
public void box() {
System.out.println("Place pizza in official PizzaStore box");
}
public String getName() {
return name;
}
}
package pizza.impl;
import pizza.Pizza;
/**
* 实现不同的风味的pizza ChicagoStyleCheesePizza
*/
public class ChicagoStyleCheesePizza extends Pizza {
/**
* 设置风味
*/
public ChicagoStyleCheesePizza() {
name = "Chicago Style Deep Dish Cheese Pizza";
dough = "Extra Thick Curst Dough";
suace = "Plum Tomato Suace";
toppings.add("Shredded Mozzarella Cheese");
}
/**
* 模拟需要有不同的切片方法
*/
@Override
public void cut() {
System.out.println("Cutting the pizza into square slices");
}
}
package pizza.impl;
import pizza.Pizza;
/**
* 实现不同的风味的pizza 纽约风味
*/
public class NYStyleCheesePizza extends Pizza {
/**
* 设置风味
*/
public NYStyleCheesePizza() {
name = "NY Style Sauce and Cheese Pizza";
dough="Thin Curst Dough";
suace="Marinara Suace";
toppings.add("Grated Reggiano Cheese");
}
}
package test;
import factory.PizzaStore;
import pizza.Pizza;
import store.ChicagoPizzaStore;
import store.NYPizzaStore;
public class BuyPizza {
public static void main(String[] args) {
// 找到NY店
PizzaStore nyPizzaStore = new NYPizzaStore();
Pizza pizza1 = nyPizzaStore.orderPizza("cheese");
System.out.println("jay order a "+pizza1.getName()+"\n");
// Chicago店
PizzaStore chicagoPizzaStore = new ChicagoPizzaStore();
Pizza pizza2 = chicagoPizzaStore.orderPizza("cheese");
System.out.println("jeff order a "+pizza2.getName()+"\n");
}
}
工厂方法让子类决定要实例化的类是哪一个,这句话的理解并不是指模式允许子类本身在运行时做出决定,而是要在编写创建者类的时候,不需要知道实际所创建的产品是哪一个,选择了使用哪一个子类,也就“决定”了实际创建的产品是什么。 接下来会出一篇关于抽象工厂模式的文章 和工厂方法模式有一定的相通性。