设计模式- 工厂相关模式
简单工厂
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 SimplePizzaFactory {
public Pizza createPizza(String type){
Pizza pizza = null;
if (type.equals("cheese")){
pizza = new CheesePizza();
}else if(type.equals("peoperoni")){
pizza = new PepperoniPizza();
}
return pizza;
}
}
工厂方法
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 abstract class PizzaStore {
public Pizza orderPizza(String type){
Pizza pizza;
pizza = CreatePizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
abstract Pizza CreatePizza(String type);
}
public class ChicagoPizzaStore extends PizzaStore {
@Override
Pizza CreatePizza(String type) {
if(type.equals("cheese")) {
return new ChicagoStyleCheesePizza();
}else{
return null;
}
}
}
public class PizzaTestDrive {
public static void main(String[] args) {
PizzaStore nyStore = new NYPizzaStore();
PizzaStore chicagoStore = new ChicagoPizzaStore();
Pizza pizza = nyStore.orderPizza("cheese");
System.out.println("Ethan ordered a " + pizza.getName() + "\n");
pizza = chicagoStore.orderPizza("cheese");
System.out.println("Joel ordered a " + pizza.getName() + "\n");
}
}
抽象工厂
综合比较各工厂模式优缺点
条件选择: 就是把要创建的产品列表,如各种pizza 放在一个if,else结构里封装成函数,传参进行选择。优点简点,缺点不符合开闭原则,耦合度高
简单工厂: 就是把创建产品列表封装成一个对象,相对来说修改只需要修改对象本身,而且对象共享使用,符合开闭原则,但是不具备扩展性。
相对来说修改只需要修改对象本身,而且对象共享使用,符合开闭原则,但是不具备扩展性。
比如你有a,b,c三款pizza,全国有几百家分店,不同地区分店pizza类别虽一样,但是调料和做法有所差异,这样你就得为不同地区建立不同的工厂以提供不同口味
的pizza,这时如果只有一个工厂就不符合了。于是有了第二种 工厂方法。
工厂方法: 就是把创建产品做成一个抽象方法,每家店可以自定义这个抽象方法。通过在基类定义createPizza为抽象方法,来实现多态,但是于此同时,你需要
创建不同pizza类,于是就有了抽象方法耦合多个pizza类。这就违反了一个原则依赖倒置原则:更高层的组件依赖具体的类,而不是依赖抽象。
在工厂方法的代码案例里,pizza的生产材料是直接创建类实例时创建的。
如何解决?
多一层抽象,还记得第一章的设置原则吗,动静分离,把不变的分成一个组件(类),把变的分成另一个(接口),然后两者组合。
原先工厂方法的是做法是:pizza是基类,继承了 area_type_pizza,所以是n * n个 pizza.
每个pizzaStore的createPizza抽象方法耦合了n个pizza实体类
现状问题:创建多个n * n pizza类,createPizza耦合多个实体类而不是抽象。
抽象工厂模式:
主要做了以下的优化
1.把pizza的生产改成根据area(提供原料)抽像成interface,解决原先抽象方法createPizza的面向具体类编程,转而改成面向PizzaIngredientFactory抽象编程。
2. pizza类的生成材料不在是每个类里单独垂直创建,而是委托工厂创建(每个店都有独立一个工厂,提供了pizza的材料)
3. 原来要创建的n(area)* n(type) 个pizza,现在变成只需要创建n个type pizza,但同时pizza的材料不再是由类写死,而是去指定区域的factory里取。但是factory指定了各种各样的材料,这个是有耦合的。
pizzaStore(is) NYPizzStore -> (has) pizza (is kind of Pizza)--> has(材料Factor) ---> has各种材料(dough、clams、pepperoni、veggies、sauce、chess不符合开闭原则) --> (is) kind of(材料)
PizzaStore(店) CreatePizza函数,需要有Pizza和factor对象。 有各种类型的pizza
Pizza -- prepare函数 (has) -- (Factor) has -- (材料)。
dough、sauce、veggies、cheese、pepperoni、clam 等材料是多态的。
工厂是不太符合开闭原则,因为要硬编码写入各种材料
抽象工厂代码

# ============ pizza的材料接口 ==================
public interface Cheese {
public String getCheese();
public String toString();
}
public interface Clams {
public String getClams();
public String toString();
}
public interface Dough {
public String getDough();
public String toString();
}
public interface Pepperoni {
public String toString();
}
public interface Sauce {
public String getSauce();
public String toString();
}
public interface Veggies {
public String toString();
}
# ============== pizza 类==============
public abstract class Pizza {
String name;
Dough dough;
Sauce sauce;
Veggies veggies[];
Cheese cheese;
Pepperoni pepperoni;
Clams clam;
abstract void prepare();
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");
}
void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public String toString(){
}
}
public class CheesePizza extends Pizza {
PizzaIngredientFactory ingredientFactory;
public CheesePizza(PizzaIngredientFactory ingredientFactory){
this.ingredientFactory = ingredientFactory;
}
@Override
void prepare() {
System.out.println("Preparing " + name);
dough = ingredientFactory.createDough();
sauce = ingredientFactory.createSauce();
cheese = ingredientFactory.createCheese();
}
}
public class VeggiePizza extends Pizza{
PizzaIngredientFactory ingredientFactory;
public VeggiePizza(PizzaIngredientFactory ingredientFactory){
this.ingredientFactory = ingredientFactory;
}
void prepare(){
System.out.println("Preparing " + name);
dough = ingredientFactory.createDough();
sauce = ingredientFactory.createSauce();
cheese = ingredientFactory.createCheese();
Veggies[] veggies = ingredientFactory.createVeggies();
}
}
# ============== Factory 接口和类 ==================
public interface PizzaIngredientFactory {
public Dough createDough();
public Sauce createSauce();
public Cheese createCheese();
public Veggies[] createVeggies();
public Pepperoni createPPeroni();
public Clams createClam();
}
public class NYPizzaIngredientFactory implements PizzaIngredientFactory {
@Override
public Dough createDough() {
return new ThinCrustDough();
}
public Sauce createSauce(){
return new MarinaraSauce();
}
public Cheese createCheese() {
return new ReggianoCheese();
}
@Override
public Veggies[] createVeggies() {
Veggies veggies[] = { new Garlic(),new Onion();new Mushroom(),new RedPepper();}
return Veggies;
}
@Override
public Pepperoni createPPeroni() {
return new SlicePepperoni();
}
@Override
public Clams createClam() {
return new FreshClams();
}
}
===============================Pizzstore =======================
public class NYPizzaStore extends PizzaStore {
protected Pizza createPizza(string item){
Pizza pizza = null;
PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();
if(item.equals("cheese")){
pizza = new CheesePizza(ingredientFactory);
pizza.setName("New York Style Cheese Pizza");
}else if (item.equals("Veggie")){
pizza = new VeggePizza(ingredientFactory);
pizza.setName("New York Style Veggie Pizza");
}else if(item.equals("clam")){
pizza = new ClamPizza(ingredientFactory);
pizza.setName("New York Style Clam Pizza");
}else if(item.equals("pepperoni")){
pizza = new PepperoniPizza(ingredientFactory);
pizza.setName("New York Style Pepperoni Pizza");
}
return pizza;
}
}