• 工厂方法


    设计原则:依赖倒置原则(要依赖抽象,不要依赖具体类)

    该设计原则的最佳实践方式的几个指导方针:

    1.变量不可以持有具体类的引用。(如果使用new,就会持有具体类的引用,可用工厂来避开这样的做法)

    2.不要类派生自具体类。(如果派生自具体类,就会依赖具体类)

    3.不要覆盖基类中已实现的方法。(如果覆盖基类已实现的方法,那么你的基类就不是一个真正适合被继承的抽象,基类中实现的方法应该由所有的子类共享)

    我们在写代码的时候尽量去追寻这些方针,将这些方针内化成你的设计的一部分(不追求代码之美的自动忽略)。

    下面回到工厂模式

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

    工厂方法的UML图:

    下面是Head First中关于工厂方法模式的PizzaDemo:

    package com.zjut.json.factoryMethod;
    
    import java.util.ArrayList;
    
    /**
     * 披萨类
     * 
     * @author json
     *
     * @date 2013-5-7
     */
    public abstract class Pizza {
        
        /**pizza的名字*/
        private String name;
        
        /**pizza的面团类型*/
        private String dough;
        
        /**pizza酱料类型*/
        private String sauce;
        
        /**pizza相关佐料*/
        @SuppressWarnings("rawtypes")
        ArrayList toppings = new ArrayList();
        
        public void prepare(){
            System.out.println("Preparing " + getName());
            System.out.println("Tossing dough...");
            System.out.println("Adding sauce...");
            System.out.println("Adding toppings: ");
            for(int i = 0; i < toppings.size(); i++){
                if(i == toppings.size()-1){
                    System.out.print( toppings.get(i));
                }else{
                    System.out.print(toppings.get(i) + ",");
                }
            }
        }
        
        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;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getDough() {
            return dough;
        }
    
        public void setDough(String dough) {
            this.dough = dough;
        }
    
        public String getSauce() {
            return sauce;
        }
    
        public void setSauce(String sauce) {
            this.sauce = sauce;
        }
    
        @SuppressWarnings("rawtypes")
        public ArrayList getToppings() {
            return toppings;
        }
    
        @SuppressWarnings("rawtypes")
        public void setToppings(ArrayList toppings) {
            this.toppings = toppings;
        }
        
    }
    package com.zjut.json.factoryMethod;
    
    /**
     * 具体风味的披萨
     * 
     * @author json
     *
     * @date 2013-5-7
     */
    public class NYStyleCheesePizza extends Pizza {
        @SuppressWarnings("unchecked")
        public NYStyleCheesePizza(){
            setName("NY Style Sauce and cheese Pizza");
            setDough("Thin Crust Dough");
            getToppings().add("Grated Reggiano Cheese");
        }
    }
    package com.zjut.json.factoryMethod;
    
    /**
     * 具体风味的Pizza
     * 
     * @author json
     *
     * @date 2013-5-7
     */
    public class ChicagoStyleCheesePizza extends Pizza {
        @SuppressWarnings("unchecked")
        public ChicagoStyleCheesePizza(){
            setName("Chicago Style Sauce and cheese Pizza");
            setDough("Extra Thick Crust Dough");
            setSauce("Plum Tomato Sauce");
            getToppings().add("Shredded Mozzarella Cheese");
        }
        
        public void cut(){
            System.out.println("Cutting the pizza into square slices");
        }
    }
    package com.zjut.json.factoryMethod;
    
    /**
     * 披萨商店
     * 
     * @author json
     *
     * @date 2013-5-7
     */
    public abstract class PizzaStore {
        
        public final  Pizza orderPizza(final String type){
            Pizza pizza;
            pizza = createPizza(type);
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
            return pizza;
        }
        
        /**
         * 创建pizza的抽象方法
         * 
         * @param type pizza的类型那个
         * 
         * @return Pizza对象
         */
        protected abstract Pizza createPizza(final String type);
    }
    package com.zjut.json.factoryMethod;
    
    /**
     * 具体披萨商店
     * 
     * @author json
     *
     * @date 2013-5-7
     */
    public class NYPizzaStore extends PizzaStore {
    
        @Override
        protected Pizza createPizza(String type) {
            if("cheese".equals(type)){
                return new NYStyleCheesePizza();
            }
            return null;
        }
    
    }
    package com.zjut.json.factoryMethod;
    
    /**
     * 具体披萨商店
     * 
     * @author json
     *
     * @date 2013-5-7
     */
    public class ChicagoPizzaStore extends PizzaStore {
    
        @Override
        protected Pizza createPizza(String type) {
            if("cheese".equals(type)){
                return new ChicagoStyleCheesePizza();
            }
            return null;
        }
    
    }

    测试类:

    package com.zjut.json.factoryMethod;
    
    /**
     * @author json
     *
     * @date 2013-5-7
     */
    public class PizzaStoreTest {
    
        public static void main(String[] args){
            PizzaStore nystore = new NYPizzaStore();
            PizzaStore chicagostore = new ChicagoPizzaStore();
            Pizza pizza = nystore.orderPizza("cheese");
            System.out.println("Json ordered a " + pizza.getName());
            pizza = chicagostore.orderPizza("cheese");
            System.out.println("Joe ordered a " + pizza.getName());
        }
    }

    测试结果:

    收工!!!

    人生最可贵的事情是sb似的坚持于追求……
  • 相关阅读:
    c#中使用SESSION需要注意的几个问题
    C#常见算法题目(面试准备)
    C# WinForm捕获未处理的异常
    c#生成注册码的两种方法(mac地址与IP地址)
    MVC3 IIS7部署记录
    c#4.0新特性之协变与逆变
    C#语言的几个层次
    C#的装箱和拆箱
    Windows下的Memcache安装
    在C#中读取枚举值的描述属性
  • 原文地址:https://www.cnblogs.com/binger/p/3065739.html
Copyright © 2020-2023  润新知