• 设计模式-工厂模式


    1、工厂模式简介

    定义:属于创建型设计模式,在工厂模式中,创建对象不会对用户暴漏创建的逻辑,通过一个共同的接口返回创建的对象

    使用场景:创建复杂的对象

    目标:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

    解决问题:解决接口选择问题

    说明:按照业务场景可分为三类:简单(静态)工厂模式、工厂模式、抽象工厂模式

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

    定义:有一个工厂类,可以产出不同类型的产品,但是当增加一个产品则需要增加一个具体的产品类和一个工厂类,违背了开闭原则

    角色:简单工厂(check)、抽象产品(staticCar)、具体产品(staticCar、staticBus)

    优点:用户无需知道所创建具体产品的类名,只需知道材料(参数)即可

         工厂类包含必要的逻辑判断,可以决定在什么时候创建哪一个产品的实例

    缺点:简单工厂模式的工厂类单一,负责所有产品的创建,职责过重,一旦异常,整个系统将受影响

         使用简单工厂模式会增加系统中类的个数(引入新的工厂类),增加系统的复杂度和理解难度

       简单工厂模式使用了 static 工厂方法,造成工厂角色无法形成基于继承的等级结构

    实现:

     1 public class staticFactory {
     2     /**
     3      * 工厂接口
     4      */
     5     public interface staticCar{
     6         void show();
     7     }
     8 
     9     /**
    10      * 产品1
    11      */
    12     static class Bus implements staticCar{
    13 
    14         @Override
    15         public void show() {
    16             System.out.println("This is a static Bus");
    17         }
    18     }
    19 
    20     /**
    21      * 产品2
    22      */
    23     static class Taxi implements staticCar{
    24 
    25         @Override
    26         public void show() {
    27             System.out.println("This is a static Taxi");
    28         }
    29     }
    30 
    31 
    32     public static class check  {
    33         /**
    34          * 判断返回哪个产品的对象
    35          * @param kind
    36          * @return
    37          */
    38          static staticCar checkFactory(int kind) {
    39             switch (kind) {
    40                 case 1:
    41                     return new Bus();
    42                 case 2:
    43                     return new Taxi();
    44             }
    45             return null;
    46         }
    47     }
    48 }

    3、工厂模式

    定义:工厂模式是对简单工厂模式的进一步抽象,增加新的产品不需要修改原来的代码,符合开闭原则

    角色:具体工厂(CarFactory)、抽象产品(Car)、具体产品(Bus、Taxi)

    优点:户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程

       灵活性增强,对于新产品的创建,只需多写一个相应的工厂类

       典型的解耦框架。高层模块只需要知道产品的抽象类,无须关心其他实现类,满足迪米特法则、依赖倒置原则和里氏替换原则

    缺点:类的个数容易过多,增加复杂度

       增加了系统的抽象性和理解难度

       抽象产品只能生产一种产品,此弊端可使用抽象工厂模式解决

    实现:

    //抽象产品
    public interface Car {
        void show();
    }
    
    //具体产品A
    public class Bus implements Car{
        @Override
        public void show() {
            System.out.println("This is a Bus");
        }
    }
    
    //具体产品B
    public class Taxi implements Car  {
        @Override
        public void show() {
            System.out.println("This is a Taxi");
        }
    }
    
    //具体工厂
    public class CarFactory {
        public Car checkCar(String kind){
            if("".equals(kind)){
                return null;
            }
            System.out.println("工厂开始生产"+kind+"产品");
            switch (kind){
                case "bus":
                    return new Bus();
    
                case "taxi":
                    return new Taxi();
            }
            return  null;
        }
    }
    
    //测试代码
    public  class Test {
        public static void main(String[] args) {
            String kind = "bus";
            Car car = new CarFactory().checkCar(kind);
            System.out.println("========================");
            car.show();
        }
    }
    //测试结果
    工厂开始生产bus产品
    ========================
    This is a Bus

    4、抽象工厂模式

    定义:一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构,属于工厂模式的升级,工厂模式中只能生产同级产品,而抽象工厂模式能生产多级产品

    角色:抽象产品(Car、Color)、具体产品(Bus、Taxi、Red、Black)、抽象工厂(AbstractFactory)、扩展抽象工厂(ACheckFactory、BCheckFactory)

    优点:可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理

       当需要产品族时,抽象工厂可以保证客户端始终只使用同一个产品的产品组

       抽象工厂增强了程序的可扩展性,当增加一个新的产品族时,不需要修改原代码,满足开闭原则

    缺点:当新增加产品时,所有的工厂类都需要更改

    实现:

    //抽象产品A
    public interface Car {
        void show();
    }
    //具体产品A1
    public class Bus implements Car {
        @Override
        public void show() {
            System.out.println("This is a abstract Bus");
        }
    }
    //具体产品A2
    public class Taxi implements Car {
        @Override
        public void show() {
            System.out.println("This is a abstract Taxi");
        }
    }
    
    //抽象产品B
    public interface Color{
        void showColor();
    }
    //抽象产品B1
    public class Red implements Color {
        @Override
        public void showColor() {
            System.out.println("This color is red");
        }
    
    }
    //抽象产品B2
    public class Black implements Color {
        @Override
        public void showColor() {
            System.out.println("This color is black");
        }
    }
    
    //抽象工厂
    public abstract class AbstractFactory {
        public abstract Car getCar();
        public abstract Color getColor();
    }
    //扩展抽象工厂A
    public class ACheckFactory extends AbstractFactory{
        @Override
        public Car getCar() {
            System.out.println("A市abstract工厂开始生产Car类产品");
            return new Bus();
        }
    
        @Override
        public Color getColor() {
            System.out.println("A市abstract工厂开始生产Color类产品");
            return new Red();
        }
    
        public void speak(){
            System.out.println("A市产品好,欢迎来购买");
        }
    }
    //扩展抽象工厂B
    public class BCheckFactory extends AbstractFactory{
        @Override
        public Car getCar() {
            System.out.println("B市abstract工厂开始生产Car类产品");
            return new Taxi();
        }
    
        @Override
        public Color getColor() {
            System.out.println("B市abstract工厂开始生产Color类产品");
            return new Black();
        }
    
        public void speak(){
            System.out.println("B市产品棒,欢迎来选购");
        }
    }
    
    //测试方法
    public  class Test {
        public static void main(String[] args) {
            System.out.println("=========A市工厂开始生产===========");
            AbstractFactory abstractFactory = new ACheckFactory();
            Color AColor = abstractFactory.getColor();
            Car ACar = abstractFactory.getCar();
            AColor.showColor();
            ACar.show();
            ((ACheckFactory) abstractFactory).speak();
    
            System.out.println("=========B市工厂开始生产===========");
            AbstractFactory bbstractFactory = new BCheckFactory();
            Color BColor = bbstractFactory.getColor();
            Car BCar = bbstractFactory.getCar();
            BColor.showColor();
            BCar.show();
            ((BCheckFactory) bbstractFactory).speak();
    
        }
    }
    //测试结果
    =========A市工厂开始生产=====================
    A市abstract工厂开始生产Color类产品
    A市abstract工厂开始生产Car类产品
    This color is red
    This is a abstract Bus
    A市产品好,欢迎来购买
    =========B市工厂开始生产=====================
    B市abstract工厂开始生产Color类产品
    B市abstract工厂开始生产Car类产品
    This color is black
    This is a abstract Taxi
    B市产品棒,欢迎来选购
  • 相关阅读:
    懵懵懂懂的样子
    scrollTop总是为0
    论搜索引擎的重要性
    利用swiper仿iphone时间设置滚轮控件
    厉害了,new Date().getTime()
    invalid Date!iphone上支持的时间格式
    我不知道的MIME
    设置canvas元素的宽高的奇妙(jiujie)发现
    用SVN在github下下载一个文件夹到本地
    c++ md5算法实现(转)
  • 原文地址:https://www.cnblogs.com/carblack/p/13737956.html
Copyright © 2020-2023  润新知