zoukankan      html  css  js  c++  java
  • 设计模式--工厂模式

    一、概述

    工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见。因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑使用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量。

    简单来说:工厂就是一种创建型的设计模式,常用于封装变化,一般遵循那里有变化就封装那里的原则。这里我们以一个快餐店为示例讲解,FastFood表示快餐,KFC表示肯德基,Mac表示麦当劳。

    FastFood.java代码如下:

    package com.Design_mode.Factory_pattern;
    
    //快餐
    public abstract class FastFood {
    
        //品牌
        public String brand;
    
        //展示
        public abstract void show();
    
    }
    

    KFC.java代码如下:

    package com.Design_mode.Factory_pattern;
    
    public class KFC extends FastFood {
        @Override
        public void show() {
            this.brand = "肯德基";
            System.out.println("欢迎来到"+ this.brand);
        }
    }
    

    Mac.java代码如下:

    package com.Design_mode.Factory_pattern;
    
    public class Mac extends FastFood {
    
        @Override
        public void show() {
            this.brand = "麦当劳";
            System.out.println("欢迎来到"+ this.brand);
        }
    
    }
    

    Student.java代码如下:

    package com.Design_mode.Factory_pattern;
    
    public class Student {
    
        public static void main(String[] args) {
            KFC kfc = new KFC();
            kfc.show();
        }
    
    }
    

    运行结果:

     从Student类中可以看到学生只允许吃KFC,如果他想吃别的东西就不允许了,违背DIP(依赖倒转原则),解决:

    package com.Design_mode.Factory_pattern;
    
    public class Student {
    
        public static void main(String[] args) {
            //这里可以指定任意FastFood子类,LSP
            //如果这里是稳定的,不会经常变化,则代码是没有问题的
            //如果这里要不断的变化,new KFC(),new Mac,new Kongfu()...
            FastFood kfc = new KFC();
            kfc.show();
        }
    
    }
    

    new KFC()就是一个变化点,封装。

    二、简单工厂(Simple Factory)

    简单工厂并不是GOF所著的书中提出的一种设计模式,但这种模式是学习设计模式一个很好的入口点,让我们能更容易理解设计模式是如何达到设计原则的要求的。
    简单工厂设计模式是一种创建型的模式,主要是用来解决对象的创建问题。

     

    上面的类图反映的就是将一组相似对象(继承自同一个类)的实例的创建放到另外一个对象中完成,即通过 ProductFactory 这个类来按需创建对象

     

    在第一节中我们提出了“封装变化”的概念,这里使用简单工厂解决问题,代码如下:

     FastFoodFactory.java代码如下:

    package com.Design_mode.Factory_pattern;
    
    /**
     * 快餐工厂
     */
    public class FastFoodFactory {
        /***
         * 用于实现不同类型快餐品牌的创建
         * @param brand 类型
         * @return 快餐品牌
         */
        public static FastFood GetFastFood(String brand) {
            switch (brand) {
                case "KFC":
                    return new KFC();
                case "Mac":
                    return new Mac();
                default:
                    throw new IllegalArgumentException("没有该品牌");
            }
        }
    
    }
    

    Student.java代码如下

    package com.Design_mode.Factory_pattern;
    
    import java.util.Scanner;
    
    public class Student {
    
        public static void main(String[] args) {
            //这里可以指定任意FastFood子类,LSP
            //如果这里是稳定的,不会经常变化,则代码是没有问题的
            //如果这里要不断的变化,new KFC(),new Mac,new Kongfu()...
            Scanner input=new Scanner(System.in);
            System.out.print("您想吃什么:");
            String brand=input.next();
    
            FastFood kfc = FastFoodFactory.GetFastFood(brand);
            kfc.show();
        }
    
    }
    

    运行结果:

    简单工厂的优点:

    简单工厂的工厂类中包含了必要的逻辑判断,这样就可以根据客户端的选择条件来动态的实例化相关的类,对于客户端来说,其去除了与具体产品之间的依赖

    简单工厂的缺点:

    违背了开-闭原则

    三、工厂方法(Factory Method)

    工厂方法模式,定义了一个用于创建对象的接口,让子类来决定要实例化哪一个类,工厂方法让类把实例化延迟到其子类。

    在工厂方法模式中主要有以下几个组成部分:

    抽象工厂:是工厂方法模式的核心,任何在模式中创建的具体工厂必须实现这个接口。

    具体工厂:这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。

    抽象产品:方法方法模式所要创建的对象的父类型,也就是产品对象的共同父类或共同拥有的接口。

    具体产品:这是实现了抽象产品所定义的接口的具体产品类的实例。这是客户端最终需要的东西。

    示例:

    KFC肯德基,Mac麦当劳,Chips薯条,Ham汉堡

    Chips.java代码如下:

    package com.Design_mode.Factory_pattern;
    
    /**
     * 抽象产品,薯条
     */
    public abstract class Chips {
    
        /**
         * 显示薯条信息
         */
        public abstract void info();
    
    }

    KFCChips.java代码如下:

    package com.Design_mode.Factory_pattern;
    
    public class KFCChips extends Chips {
        @Override
        public void info() {
            System.out.println("肯德基薯条");
        }
    }

    MacChips.java代码如下:

    package com.Design_mode.Factory_pattern;
    
    public class MacChips extends Chips {
        @Override
        public void info() {
            System.out.println("麦当劳薯条");
        }
    }

    Ham.java代码如下:

    package com.Design_mode.Factory_pattern;
    
    /**
     * 抽象产品,汉堡
     */
    public abstract class Ham {
    
        /**
         * 显示汉堡信息
         */
        public abstract void show();
    
    }

    KFCHam.java代码如下:

    package com.Design_mode.Factory_pattern;
    
    public class KFCHam extends Ham {
        @Override
        public void show() {
            System.out.println("肯德基汉堡");
        }
    }

    MacHam.java代码如下:

    package com.Design_mode.Factory_pattern;
    
    public class MacHam extends Ham {
        @Override
        public void show() {
            System.out.println("麦当劳汉堡");
        }
    }

    FastFoodFactoryAb.java代码如下:

    package com.Design_mode.Factory_pattern;
    
    /**
     * 抽象工厂 快餐工厂
     */
    public abstract class FastFoodFactoryAb {
    
        /**
         * 生产汉堡
         */
        public abstract Ham CreateHam();
    
        /**
         * 生产薯条
         */
        public abstract Chips CreateChips();
    
        /***
         * 用于实现不同类型快餐品牌的创建
         * @param brand 类型
         * @return 快餐品牌
         */
        public static FastFoodFactoryAb GetFastFood(String brand) {
            switch (brand) {
                case "KFC":
                    return new KFCFactory();
                case "Mac":
                    return new MacFactory();
                default:
                    throw new IllegalArgumentException("没有该品牌");
            }
        }
    }

    KFCFactory.java代码如下:

    package com.Design_mode.Factory_pattern;
    
    public class KFCFactory extends FastFoodFactoryAb {
        @Override
        public Ham CreateHam() {
            return new KFCHam();
        }
    
        @Override
        public Chips CreateChips() {
            return new KFCChips();
        }
    }

    MacFactory.java代码如下:

    package com.Design_mode.Factory_pattern;
    
    public class MacFactory extends FastFoodFactoryAb {
        @Override
        public Ham CreateHam() {
            return new MacHam();
        }
    
        @Override
        public Chips CreateChips() {
            return new MacChips();
        }
    }

    Student.java代码如下:

    package com.Design_mode.Factory_pattern;
    
    import java.util.Scanner;
    
    public class Student {
    
        public static void main(String[] args) {
            //这里可以指定任意FastFood子类,LSP
            //如果这里是稳定的,不会经常变化,则代码是没有问题的
            //如果这里要不断的变化,new KFC(),new Mac,new Kongfu()...
            Scanner input=new Scanner(System.in);
            System.out.print("您想吃什么:");
            String brand=input.next();
    
            FastFoodFactoryAb fastFood = FastFoodFactoryAb.GetFastFood(brand);
            fastFood.CreateHam().show();
            fastFood.CreateChips().info();
        }
    
    }

    运行结果:

    原文来自:https://www.cnblogs.com/best/p/7762841.html

  • 相关阅读:
    团队选题报告
    第二次结对作业
    高级软件工程团队第一次作业
    第一次结队作业
    高级软件工程第二次作业
    高级软件工程第一次作业
    洛谷 题解 2165 [AHOI2009]飞行棋
    洛谷 题解 P1684 考验
    洛谷 题解 P4613 【[COCI2017-2018#5] Olivander】
    洛谷 题解 P5534 【【XR-3】等差数列】
  • 原文地址:https://www.cnblogs.com/Qi1007/p/10093027.html
Copyright © 2011-2022 走看看