02.工厂设计模式

简单工厂模式(静态工厂模式)

  • 简单工厂模式是属于创建型模式,是工厂模式的的一种,简单工厂模式是有一个工厂对象决定创建出那一种产品类的实例。简单工厂模式是工厂模式家族的最简单实用的模式。

  • 简单工厂模式:定义一个创建对象的类,由这个类来创建实例化对象的行为(代码)

  • 在软件开发当中,当我们会用到大量的创建某种、某类或者某批对象时,就会使用工厂模式。

  • 代码示例:

    /**
     * @author 通过程序看世界
     * @version 1.0
     * 将Pizza做成抽象类
     */
    public abstract class Pizza {
        protected String name; //披萨的名字
    
        //准备原材料,不同的披萨不一样,因此.我们做成抽象方法
        public abstract void prepare();
    
        public void bake() {
            System.out.println(name + "backing");
        }
    
        public void cut() {
            System.out.println(name + "cutting");
        }
    
        //打包
        public void box() {
            System.out.println(name + "boxing");
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
    }
    
    /**
     * @author 通过程序看世界
     * @version 1.0
     * 奶酪披萨
     */
    public class CheesePizza extends Pizza {
        @Override
        public void prepare() {
            System.out.println("给制作奶酪披萨准备原材料");
        }
    }
    
    /**
     * @author 通过程序看世界
     * @version 1.0
     * 希腊披萨
     */
    public class GreekPizza extends Pizza{
        @Override
        public void prepare() {
            System.out.println("给希腊披萨准备原材料");
        }
    }
    
    /**
     * @author 通过程序看世界
     * @version 1.0
     * 简单工厂类
     */
    public class SimpleFactor {
        //根据orderType返回对应的Pizza对象
        public Pizza createPizza(String type) {
            System.out.println("使用简单工厂模式");
            Pizza pizza = null;
            if (type.equals("greek")){
                pizza = new CheesePizza();
                pizza.setName("希腊披萨");
            }else if (type.equals("cheese")){
                pizza = new CheesePizza();
                pizza.setName("奶酪披萨");
            }
            return pizza;
        }
    }
    
    
    /**
     * @author 通过程序看世界
     * @version 1.0
     * 订购披萨的类
     */
    public class OrderPizza {
        //定义一个一个简单工厂对象
        SimpleFactor simpleFactor;
        Pizza pizza;
    
        public OrderPizza(SimpleFactor simpleFactor) {
            setSimpleFactor(simpleFactor);
        }
    
        public void setSimpleFactor(SimpleFactor simpleFactor) {
            String type = ""; //用户输入
            this.simpleFactor = simpleFactor; //设置简单工厂对象
            do {
                type = getType();
                pizza = this.simpleFactor.createPizza(type);
    
                //输出pizza
                if (pizza != null) {
                    pizza.prepare();
                    pizza.bake();
                    pizza.cut();
                    pizza.box();
                } else {
                    System.out.println("订购pizza失败!");
                    break;
                }
            } while (true);
    
        }
    
    
    
        //写一个方法,可以获取客户希望订购的Pizza种类
        private String getType() {
            try {
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
                System.out.println("input pizza type:");
                String str = bufferedReader.readLine();
                return str;
            } catch (IOException e) {
                e.printStackTrace();
            }
            return "";
        }
    
    }
    
    /**
     * @author 通过程序看世界
     * @version 1.0
     * 相当于一个客户端
     */
    public class PizzaStore {
        public static void main(String[] args) {
            new OrderPizza(new SimpleFactor());
            System.out.println("退出程序");
        }
    }
    
  • 程序运行结果

    input pizza type:
    cheese
    使用简单工厂模式
    给制作奶酪披萨准备原材料
    奶酪披萨backing
    奶酪披萨cutting
    奶酪披萨boxing
    input pizza type:
    greek
    使用简单工厂模式
    给制作奶酪披萨准备原材料
    希腊披萨backing
    希腊披萨cutting
    希腊披萨boxing
    input pizza type:
    
  • 代码分析

    • 后期我们需要增加新的披萨类型,只需要在创建一个披萨类,在工厂类当中做出if判断处理即可

工厂方式模式

  • 定义一个创建对象的抽象方法,由子类决定要实例化的类,工厂方法模式将对象的实例化推迟到子类。

  • 需求:客户在点披萨的时候,可以点不同口味的披萨。比如:北京的奶酪pizza、北京的胡椒pizza、或者伦敦的奶酪pizza、伦敦的胡椒pizza

  • 代码实例:

    package com.db.factormethod.pizza;
    
    /**
     * @author 通过程序看世界
     * @version 1.0
     * 将Pizza做成抽象类
     */
    public abstract class Pizza {
        protected String name; //准备
    
        //准备原材料,不同的披萨不一样,因此.我们做成抽象方法
        public abstract void prepare();
    
        public void bake() {
            System.out.println(name + "backing");
        }
    
        public void cut() {
            System.out.println(name + "cutting");
        }
    
        //打包
        public void box() {
            System.out.println(name + "boxing");
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
    package com.db.factormethod.pizza;
    
    /**
     * @author 通过程序看世界
     * @version 1.0
     * 伦敦的胡椒披萨
     */
    public class LDPepperPizza extends Pizza{
        @Override
        public void prepare() {
            setName("伦敦的胡椒披萨");
            System.out.println("为伦敦的胡椒披萨准备原材料");
        }
    }
    
    package com.db.factormethod.pizza;
    
    /**
     * @author 通过程序看世界
     * @version 1.0
     * 伦敦的胡椒披萨
     */
    public class LDCheesePizza extends Pizza{
        @Override
        public void prepare() {
            setName("伦敦的胡椒披萨");
            System.out.println("为伦敦的胡椒披萨准备原材料");
        }
    }
    
    
    package com.db.factormethod.pizza;
    
    /**
     * @author 通过程序看世界
     * @version 1.0
     */
    public class BJPepperPizza extends Pizza{
        @Override
        public void prepare() {
            setName("北京的胡椒披萨");
            System.out.println("为北京的胡椒披萨准备原材料");
        }
    }
    
    
    package com.db.factormethod.pizza;
    
    /**
     * @author 通过程序看世界
     * @version 1.0
     */
    public class BJCheesePizza extends Pizza{
        @Override
        public void prepare() {
            setName("北京奶酪披萨");
            System.out.println("为北京的奶酪pizza准备原材料");
        }
    }
    
    
    package com.db.factormethod.order;
    import com.db.factor.order.SimpleFactor;
    import com.db.factormethod.pizza.Pizza;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    /**
     * @author 通过程序看世界
     * @version 1.0
     * 订购披萨的类
     */
    public abstract class OrderPizza {
    
    
        public OrderPizza() {
            Pizza pizza = null;
            String type; //订购披萨的类型
            do {
                type = getType();
                pizza = createPizza(type);
                //输出Pizza的制作过程
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.bake();
            } while (true);
        }
    
        //定义一个抽象方法,createPizza,让各个工厂类自己去实现
        public abstract Pizza createPizza(String type);
    
        //写一个方法,可以获取客户希望订购的Pizza种类
        private String getType() {
            try {
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
                System.out.println("input pizza type:");
                String str = bufferedReader.readLine();
                return str;
            } catch (IOException e) {
                e.printStackTrace();
            }
            return "";
        }
    }
    
    
    package com.db.factormethod.order;
    
    import com.db.factormethod.pizza.LDCheesePizza;
    import com.db.factormethod.pizza.LDPepperPizza;
    import com.db.factormethod.pizza.Pizza;
    
    /**
     * @author 通过程序看世界
     * @version 1.0
     * 伦敦订购披萨的类
     */
    public class LDOrderPizza extends OrderPizza {
        @Override
        public Pizza createPizza(String type) {
            Pizza pizza = null;
            if (type.equals("cheese")) {
                pizza = new LDCheesePizza();
            } else if (type.equals("pepper")) {
                pizza = new LDPepperPizza();
            }
            return pizza;
        }
    }
    
    package com.db.factormethod.order;
    import com.db.factormethod.pizza.BJCheesePizza;
    import com.db.factormethod.pizza.BJPepperPizza;
    import com.db.factormethod.pizza.Pizza;
    
    /**
     * @author 通过程序看世界
     * @version 1.0
     * 北京订购披萨的类
     */
    public class BJOrderPizza extends OrderPizza{
    
        @Override
        public Pizza createPizza(String type) {
            Pizza pizza = null;
            if (type.equals("cheese")){
                pizza = new BJCheesePizza();
            }else if (type.equals("pepper")){
                pizza = new BJPepperPizza();
            }
            return pizza;
        }
    }
    
    package com.db.factormethod.order;
    
    /**
     * @author 通过程序看世界
     * @version 1.0
     */
    public class PizzaStore {
        public static void main(String[] args) {
            new BJOrderPizza();
        }
    }
    
  • 运行结果

input pizza type:
cheese
为北京的奶酪pizza准备原材料
北京奶酪披萨backing
北京奶酪披萨cutting
北京奶酪披萨backing
input pizza type:
pepper
为北京的胡椒披萨准备原材料
北京的胡椒披萨backing
北京的胡椒披萨cutting
北京的胡椒披萨backing

抽象工厂模式

抽象工厂模式

  • 抽象工厂模式,定义了一个interface用于创建相关或者有依赖关系的对象簇,而无需指明具体的类

  • 抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合

  • 从设计层面来看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)

  • 将工厂抽象成两层,AbsFactory(抽象工厂)和具体实现的工厂子类,程序员可以根据创建对象类型使用相应的工厂子类。这样将单个的简单工厂类变成了工厂簇,更加有利于代码的维护和扩展

  • 代码示例:

    package com.db.absfactory.pizza;
    
    /**
     * @author 通过程序看世界
     * @version 1.0
     * 将Pizza做成抽象类
     */
    public abstract class Pizza {
        protected String name; //准备
    
        //准备原材料,不同的披萨不一样,因此.我们做成抽象方法
        public abstract void prepare();
    
        public void bake() {
            System.out.println(name + "backing");
        }
    
        public void cut() {
            System.out.println(name + "cutting");
        }
    
        //打包
        public void box() {
            System.out.println(name + "boxing");
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
    }
    
    
    package com.db.absfactory.pizza;
    
    /**
     * @author 通过程序看世界
     * @version 1.0
     * 伦敦的胡椒披萨
     */
    public class LDPepperPizza extends Pizza {
        @Override
        public void prepare() {
            setName("伦敦的胡椒披萨");
            System.out.println("为伦敦的胡椒披萨准备原材料");
        }
    }
    
    
    package com.db.absfactory.pizza;
    
    /**
     * @author 通过程序看世界
     * @version 1.0
     * 伦敦的胡椒披萨
     */
    public class LDCheesePizza extends Pizza {
        @Override
        public void prepare() {
            setName("伦敦的胡椒披萨");
            System.out.println("为伦敦的胡椒披萨准备原材料");
        }
    }
    
    
    package com.db.absfactory.pizza;
    
    /**
     * @author 通过程序看世界
     * @version 1.0
     */
    public class BJPepperPizza extends Pizza {
        @Override
        public void prepare() {
            setName("北京的胡椒披萨");
            System.out.println("为北京的胡椒披萨准备原材料");
        }
    }
    
    package com.db.absfactory.pizza;
    
    /**
     * @author 通过程序看世界
     * @version 1.0
     */
    public class BJCheesePizza extends Pizza {
        @Override
        public void prepare() {
            setName("北京奶酪披萨");
            System.out.println("为北京的奶酪pizza准备原材料");
        }
    }
    
    package com.db.absfactory.order;
    
    import com.db.absfactory.pizza.Pizza;
    
    /**
     * @author 通过程序看世界
     * @version 1.0
     * 抽象工厂模式的抽象层(接口)
     */
    public interface IAbsFactory {
        //让下面的工厂子类去具体实现
        public Pizza createPizza(String type);
    }
    
    package com.db.absfactory.order;
    
    import com.db.absfactory.pizza.BJCheesePizza;
    import com.db.absfactory.pizza.BJPepperPizza;
    import com.db.absfactory.pizza.Pizza;
    
    /**
     * @author 通过程序看世界
     * @version 1.0
     * 北京的工厂
     */
    public class BJFactor implements IAbsFactory {
        @Override
        public Pizza createPizza(String type) {
            System.out.println("使用抽象工厂模式");
            Pizza pizza = null;
            if (type.equals("cheese")){
                pizza = new BJCheesePizza();
            }else if(type.equals("pepper")){
                pizza = new BJPepperPizza();
            }
            return pizza;
        }
    }
    
    package com.db.absfactory.order;
    
    import com.db.absfactory.pizza.*;
    
    /**
     * @author 通过程序看世界
     * @version 1.0
     */
    public class LDFactor implements IAbsFactory{
        @Override
        public Pizza createPizza(String type) {
            System.out.println("使用抽象工厂模式");
            Pizza pizza = null;
            if (type.equals("cheese")){
                pizza = new LDCheesePizza();
            }else if(type.equals("pepper")){
                pizza = new LDPepperPizza();
            }
            return pizza;
        }
    }
    
    package com.db.absfactory.order;
    
    import com.db.absfactory.pizza.Pizza;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    /**
     * @author 通过程序看世界
     * @version 1.0
     * 订购披萨的类
     */
    public class OrderPizza {
        IAbsFactory iAbsFactory;
    
        public OrderPizza(IAbsFactory iAbsFactory) {
            setiAbsFactory(iAbsFactory);
        }
    
        public void setiAbsFactory(IAbsFactory iAbsFactory) {
            this.iAbsFactory = iAbsFactory;
            String type = "";
            Pizza pizza = null;
            do {
                type = getType();
                pizza = iAbsFactory.createPizza(type);
                //输出披萨的制作guoc
                if (pizza != null) {
                    pizza.prepare();
                    pizza.bake();
                    pizza.cut();
                    pizza.box();
                }else {
                    System.out.println("订购失败");
                }
            } while (true);
        }
    
        //写一个方法,可以获取客户希望订购的Pizza种类
        private String getType() {
            try {
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
                System.out.println("input pizza type:");
                String str = bufferedReader.readLine();
                return str;
            } catch (IOException e) {
                e.printStackTrace();
            }
            return "";
        }
    
    }
    
    package com.db.absfactory.order;
    
    import com.sun.org.apache.bcel.internal.generic.NEW;
    
    /**
     * @author 通过程序看世界
     * @version 1.0
     */
    public class PizzaStore {
        public static void main(String[] args) {
            new OrderPizza(new BJFactor());
        }
    }
    
  • 运行结果

    input pizza type:
    pepper
    使用抽象工厂模式
    为北京的胡椒披萨准备原材料
    北京的胡椒披萨backing
    北京的胡椒披萨cutting
    北京的胡椒披萨boxing
    input pizza type:
    cheese
    使用抽象工厂模式
    为北京的奶酪pizza准备原材料
    北京奶酪披萨backing
    北京奶酪披萨cutting
    北京奶酪披萨boxing
    

JDK当中的工厂模式

Calendar源码分析

Calendar类当中的createCalendar方法就是采用了简单工厂模式,根据传输的不同的aLocale 返回不同的Calendar实例

 private static Calendar createCalendar(TimeZone zone,
                                           Locale aLocale)
    {
       Calendar cal = null;
       if (aLocale.hasExtensions()) {
            String caltype = aLocale.getUnicodeLocaleType("ca");
            if (caltype != null) {
                switch (caltype) {
                case "buddhist":
                cal = new BuddhistCalendar(zone, aLocale);
                    break;
                case "japanese":
                    cal = new JapaneseImperialCalendar(zone, aLocale);
                    break;
                case "gregory":
                    cal = new GregorianCalendar(zone, aLocale);
                    break;
                }
            }
        }
        return cal;
    }

工厂模式的总结

  1. 工厂模式的意义
    1. 将实例化对象的代码提取出来,放到一个类当中进行统一管理和维护,达到和主项目的依赖关系的解耦合,从而提高项目的扩展性和维护性
  2. 三种工厂模式
    1. 简单工厂模式
    2. 工厂方法模式
    3. 抽象工厂模式
  3. 设计模式的依赖抽象原则
    1. 创建对象实例的时候,不要直接new类,而是把这个new类的动作放到一个工厂的方法当中,并且返回,有的书上说,变量不要直接持有具体类的引用。
    2. 不要让类继承具体类,而是继承抽象类或者实现接口
    3. 不要覆盖基类中已经实现的方法
posted @ 2022-12-10 13:10  通过程序看世界  阅读(43)  评论(0)    收藏  举报