zoukankan      html  css  js  c++  java
  • 创建型模式之工厂模式

    一、简单工厂模式

    1、介绍

    简单工厂模式是工厂模式家族中最简单使用的模式,它定义了一个创建对象的类,由这个类来封装实例化对象的行为。在软件开发中,当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式。

    2、类图

    3、例子

    看一个披萨的项目:

    1. 披萨的种类很多(比如:GreekPizza、CheesePizza)
    2. 披萨的制作有 prepare、bake、cut、box
    3. 完成披萨店订购功能

    3.1、披萨类

    /**
     * 披萨类接口
     */
    public abstract class Pizza {
        protected String name;
    
        public abstract void prepare();
    
        public void bake(){
            System.out.println(name + " baking;");
        }
    
        public void cut(){
            System.out.println(name + " cutting;");
        }
    
        public void box(){
            System.out.println(name + "boxing;");
        }
    
        public void setName(String name){
            this.name = name;
        }
    }
    
    /**
     * 奶酪披萨
     */
    public class CheesePizza extends Pizza {
        @Override
        public void prepare() {
            System.out.println(" 准备材料制作奶酪披萨 ");
        }
    }
    
    /**
     * 希腊披萨
     */
    public class GreekPizza extends Pizza {
        @Override
        public void prepare() {
            System.out.println(" 准备材料制作希腊披萨 ");
        }
    }
    
    /**
     * 胡椒披萨
     */
    public class PepperPizza extends Pizza {
        @Override
        public void prepare() {
            System.out.println(" 准备制作胡椒披萨 ");
        }
    }
    

    3.2、实例化类

    /**
     * 实例化功能
     */
    public class OrderPizza {
    
        SimpleFactoty simpleFactoty;
        Pizza pizza = null;
    
        public OrderPizza(SimpleFactoty simpleFactoty){
            setFactory(simpleFactoty);
        }
    
        public void setFactory(SimpleFactoty simpleFactoty){
            String orderType = "";
            this.simpleFactoty = simpleFactoty;
            do{
                orderType = getType();
                pizza = this.simpleFactoty.createPizza(orderType);
                if(pizza != null){
                    pizza.prepare();
                    pizza.bake();
                    pizza.cut();
                    pizza.box();
                }else {
                    System.out.println(" 订购失败 ");
                    break;
                }
            }while(true);
        }
    
        // 写一个方法,可以获取客户希望订购的披萨种类
        private String getType(){
            try {
                BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
                System.out.println("请输入披萨种类:");
                String str = strin.readLine();
                return str;
            } catch (IOException e) {
                e.printStackTrace();
                return "";
            }
        }
    }
    

    3.3、简单工厂类

    /**
     * 简单工厂类
     */
    public class SimpleFactoty {
    
        public Pizza createPizza(String orderType){
    
            Pizza pizza = null;
    
            System.out.println("实用简单工厂模式");
            if(orderType.equals("cheese")){
                pizza = new CheesePizza();
                pizza.setName(" 奶酪披萨 ");
            }else if(orderType.equals("greek")){
                pizza = new GreekPizza();
                pizza.setName(" 希腊披萨 ");
            }else if(orderType.equals("pepper")){
                pizza = new PepperPizza();
                pizza.setName(" 胡椒披萨 ");
            }
    
            return pizza;
        }
    }
    

    3.4、商店类

    /**
     * 商店类
     */
    public class PizzaStore {
        public static void main(String[] args) {
            new OrderPizza(new SimpleFactoty());
        }
    }
    

    二、工厂方法模式

    1、介绍

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

    2、类图

    3、例子

    披萨项目的新需求:

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

    3.1、披萨类

    /**
     * 披萨类接口
     */
    public abstract class Pizza {
        protected String name;
    
        public abstract void prepare();
    
        public void bake(){
            System.out.println(name + " baking;");
        }
    
        public void cut(){
            System.out.println(name + " cutting;");
        }
    
        public void box(){
            System.out.println(name + " boxing");
        }
    
        public void setName(String name){
            this.name = name;
        }
    }
    
    /**
     * 北京奶酪披萨
     */
    public class BJCheesePizza extends Pizza {
    
        @Override
        public void prepare() {
            setName(" 北京的奶酪披萨 ");
            System.out.println(" 准备制作北京奶酪披萨 ");
        }
    }
    
    /**
     * 北京胡椒披萨
     */
    public class BJPepperPizza extends Pizza {
        @Override
        public void prepare() {
            setName(" 北京的胡椒披萨 ");
            System.out.println(" 准备制作北京胡椒披萨 ");
        }
    }
    
    /**
     * 伦敦奶酪披萨
     */
    public class LDCheesePizza extends Pizza {
        @Override
        public void prepare() {
            setName(" 伦敦的奶酪披萨 ");
            System.out.println(" 准备制作伦敦奶酪披萨 ");
        }
    }
    
    /**
     * 伦敦胡椒披萨
     */
    public class LDPepperPizza extends Pizza {
        @Override
        public void prepare() {
            setName(" 伦敦的胡椒披萨 ");
            System.out.println(" 准备制作伦敦胡椒披萨 ");
        }
    }
    

    3.2、实例化类

    /**
     * 实例化类接口
     */
    public abstract class OrderPizza {
        abstract Pizza createPizza(String orderType);
    
        public OrderPizza(){
            Pizza pizza = null;
            String orderType = "";
            do{
                orderType = getType();
                pizza=createPizza(orderType);
                if(pizza != null){
                    pizza.prepare();
                    pizza.bake();
                    pizza.cut();
                    pizza.box();
                }else {
                    System.out.println(" 订购失败 ");
                    break;
                }
            }while(true);
        }
    
        // 写一个方法,可以获取客户希望订购的披萨种类
        private String getType(){
            try {
                BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
                System.out.println("请输入披萨种类:");
                String str = strin.readLine();
                return str;
            } catch (IOException e) {
                e.printStackTrace();
                return "";
            }
        }
    }
    
    /**
     * 北京的实例化类
     */
    public class BJOrderPizza extends OrderPizza {
        @Override
        Pizza createPizza(String orderType) {
            Pizza pizza = null;
            if(orderType.equals("cheese")){
                pizza = new BJCheesePizza();
            }else if(orderType.equals("pepper")){
                pizza = new BJPepperPizza();
            }
    
            return pizza;
        }
    }
    
    /**
     * 伦敦的实例化类
     */
    public class LDOrderPizza extends OrderPizza {
        @Override
        Pizza createPizza(String orderType) {
            Pizza pizza = null;
            if(orderType.equals("cheese")){
                pizza = new LDCheesePizza();
            }else if(orderType.equals("pepper")){
                pizza = new LDPepperPizza();
            }
    
            return pizza;
        }
    }
    

    3.3、商店类

    /**
     * 商店类
     */
    public class PizzaStore {
        public static void main(String[] args) {
    //        new BJOrderPizza();
            new LDOrderPizza();
        }
    }
    

    三、抽象工厂模式

    1、介绍

    1. 抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合。
    2. 从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)。
    3. 将工厂抽象成两层,AbsFactory(抽象工厂)和 具体实现的工厂子类。程序员可以根据创建对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和而扩展。

    2、类图

    3、例子

    需求跟第二个一样。

    3.1、披萨类

    /**
     * 披萨类接口
     */
    public abstract class Pizza {
        protected String name;
    
        public abstract void prepare();
    
        public void bake(){
            System.out.println(name + " baking;");
        }
    
        public void cut(){
            System.out.println(name + " cutting;");
        }
    
        public void box(){
            System.out.println(name + " boxing");
        }
    
        public void setName(String name){
            this.name = name;
        }
    }
    
    /**
     * 北京奶酪披萨
     */
    public class BJCheesePizza extends Pizza {
    
        @Override
        public void prepare() {
            setName(" 北京的奶酪披萨 ");
            System.out.println(" 准备制作北京奶酪披萨 ");
        }
    }
    
    /**
     * 北京胡椒披萨
     */
    public class BJPepperPizza extends Pizza {
        @Override
        public void prepare() {
            setName(" 北京的胡椒披萨 ");
            System.out.println(" 准备制作北京胡椒披萨 ");
        }
    }
    
    /**
     * 伦敦奶酪披萨
     */
    public class LDCheesePizza extends Pizza {
        @Override
        public void prepare() {
            setName(" 伦敦的奶酪披萨 ");
            System.out.println(" 准备制作伦敦奶酪披萨 ");
        }
    }
    
    /**
     * 伦敦胡椒披萨
     */
    public class LDPepperPizza extends Pizza {
        @Override
        public void prepare() {
            setName(" 伦敦的胡椒披萨 ");
            System.out.println(" 准备制作伦敦胡椒披萨 ");
        }
    }
    

    3.2、实例化类

    /**
     * 实例化功能
     */
    public class OrderPizza {
        AbsFactory factory;
    
        // 构造器
        public OrderPizza(AbsFactory factory){
            setFactory(factory);
        }
    
        public void setFactory(AbsFactory factory){
            Pizza pizza = null;
            String orderType = "";// 用户输入
            this.factory = factory;
            do{
                orderType = getType();
                // factory 可能是北京的工厂子类,也可能是伦敦的工厂子类
                pizza = factory.createPizza(orderType);
                if(pizza != null){
                    pizza.prepare();
                    pizza.bake();
                    pizza.cut();
                    pizza.box();
                }else {
                    System.out.println(" 订购失败 ");
                    break;
                }
            }while(true);
        }
    
        // 写一个方法,可以获取客户希望订购的披萨种类
        private String getType(){
            try {
                BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
                System.out.println("请输入披萨种类:");
                String str = strin.readLine();
                return str;
            } catch (IOException e) {
                e.printStackTrace();
                return "";
            }
        }
    }
    

    3.3、工厂类

    /**
     * 工厂类接口
     */
    public interface AbsFactory {
        //让下面的工厂子类来 具体实现
        public Pizza createPizza(String orderType);
    }
    
    /**
     * 北京工厂类
     */
    public class BJFactory implements AbsFactory {
    
        @Override
        public Pizza createPizza(String orderType) {
            System.out.println("~使用的是抽象工厂模式~");
            Pizza pizza = null;
    
            if(orderType.equals("cheese")){
                pizza = new BJCheesePizza();
            }else if(orderType.equals("pepper")){
                pizza = new BJPepperPizza();
            }
            return pizza;
        }
    }
    
    /**
     * 伦敦工厂类
     */
    public class LDFactory implements AbsFactory {
        @Override
        public Pizza createPizza(String orderType) {
            System.out.println("~使用的是抽象工厂模式~");
            Pizza pizza = null;
    
            if(orderType.equals("cheese")){
                pizza = new LDCheesePizza();
            }else if(orderType.equals("pepper")){
                pizza = new LDPepperPizza();
            }
            return pizza;
        }
    }
    

    3.4、商店类

    /**
     * 商店类
     */
    public class PizzaStore {
        public static void main(String[] args) {
    //        new OrderPizza(new BJFactory());
            new OrderPizza(new LDFactory());
        }
    }
    
  • 相关阅读:
    通过Relect反射方法创建对象,获得对象的方法,输出对象信息
    Spring框架中获取连接池常用的四种方式
    Spring框架的七大模块
    Java线程池的四种创建方式
    递归算法
    将字符串反转的 Java 方法
    [String]split()方法
    [String] intern()方法
    案例>>>用绝对值的方法打印出菱形
    数组的简单理解
  • 原文地址:https://www.cnblogs.com/xiaoran991/p/12622688.html
Copyright © 2011-2022 走看看