引入


定义:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

认识工厂模式

工厂方法模式(Factory Method Pattern)定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个,工厂方法让类把实例化推迟到子类,这样的设计将对象的创建封装其来,以便于得到更松耦合,更有弹性的设计。 

需要生成的对象叫做产品 ,生成对象的地方叫做工厂

 

UML类图

示例

披萨工厂例子

Product类

package com.zpkj.project9;

import java.util.ArrayList;

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,j=toppings.size();i<j;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;
     }
        
}

Product产品实现类

package com.zpkj.project9;

public class NYStyleClamPizza extends Pizza{
    
    public NYStyleClamPizza() {
        name="NY Style Sauce and Cheese Pizza";
        dough="Thin Crust Dough";
        sauce="Marinara Sauce";
        toppings.add("Grated Reggiano Cheese");
    }

    @Override
    public void prepare() {
        System.out.println("准备");
    }

    @Override
    public void bake() {
        System.out.println("烘焙");
    }

    @Override
    public void cut() {
        System.out.println("切割");
    }

    @Override
    public void box() {
        System.out.println("装盒");
    }


}


 

package com.zpkj.project9;
/**
 * 子类实例化工厂方法
 */
public class NYStyleCheesePizza extends Pizza{

    @Override
    public void prepare() {
        System.out.println("准备");
    }

    @Override
    public void bake() {
        System.out.println("烘焙");
    }

    @Override
    public void cut() {
        System.out.println("切割");
    }

    @Override
    public void box() {
        System.out.println("装盒");
    }

}
package com.zpkj.project9;

public class NYStylePepperoniPizza extends Pizza{

    @Override
    public void prepare() {
        System.out.println("准备");
    }

    @Override
    public void bake() {
        System.out.println("烘焙");
    }

    @Override
    public void cut() {
        System.out.println("切割");
    }

    @Override
    public void box() {
        System.out.println("装盒");
    }


}

 

package com.zpkj.project9;

public class NYStyleVeggiePizza extends Pizza {

    @Override
    public void prepare() {
        System.out.println("准备");
    }

    @Override
    public void bake() {
        System.out.println("烘焙");
    }

    @Override
    public void cut() {
        System.out.println("切割");
    }

    @Override
    public void box() {
        System.out.println("装盒");
    }

}

 

抽象工厂

package com.zpkj.project9;

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);

}

具体工厂

package com.zpkj.project9;

public class NYPizzaStore extends PizzaStore{
    
    /**
     * 具体工厂
     */
    @Override
    Pizza createPizza(String type) {
        if(type.equals("cheese")){
            return new NYStyleCheesePizza();
        }else if(type.equals("clam")){
            return new NYStyleClamPizza();
        }else if(type.equals("veggie")){
            return new NYStyleVeggiePizza();
        }else if(type.equals("pepperoni")){
            return new NYStylePepperoniPizza();
        }else 
         return null;
    }

}

测试

package com.zpkj.project9;

public class Main {
    public static void main(String[] args) {
        
        PizzaStore pizzaStore = new NYPizzaStore();
        Pizza createPizza = pizzaStore.orderPizza("clam");
        System.out.println(createPizza.name);
        System.out.println(createPizza.dough);
        System.out.println(createPizza.sauce);
        System.out.println(createPizza.toppings);
    }
    
}

结果

oo原则

遵循OO设计原则,依赖倒置远侧:'要依赖抽象,不要依赖具体类'

想要遵循依赖倒置原则,工厂方法是最有威力的技巧之一。

设计方针(尽量达到原则):

1.变量不可持有具体类的引用

2.不要让类派生自具体类,(一般派生接口或抽象类)

3.不要覆盖基类中已实现的方法

总结

1.所有的工厂都是用来封装对象的创建

2.简单工厂,虽然不是真正的设计模式,但任不失为一个简单的方法,可以将客户程序从具体类解耦

3.工厂方法使用继承;把对象的创建委托给子类,子类实现工厂方法来创建对象

4.抽象工厂使用对象组合;对象的创建被实现在工厂接口所暴露出来的方法中

5.所有工厂模式都通过减少应用程序和具体类之间的依赖促进松耦合

6.工厂方法允许类将实例化延迟到子类进行

引用

[1] 弗里曼. Head First 设计模式(中文版)[Z]. 中国电力出版社: O'Reilly Taiwan公司 ,2007.

源码下载

https://github.com/isheroleon/design

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐