• 工厂模式


    简介

    工厂模式是java中最常用的设计模式之一,这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同接口来指向新创建的对象,其意思是代码编写出来是为了给别人调用的:

    • 调用者跟代码编写者可能是同一个人,也可能是不同人
    • 提供给调用者的代码,有可能是源码可见的,也可能是源码不可见、不可修改的(比如jar包)

    所以,为了简化代码的协作使用及管理维护,必须想尽办法简化代码逻辑,实现必要的分离。

    1、最原始的方式

    比如说,创建不同品牌的手机

    // 苹果品牌手机类
    public class Iphone {
        public void xxx () {
            System.out.println("我是苹果手机");
        }
    }
    
    //华为品牌手机类
    public class Huawei {
        public void yyy () {
            System.out.println("我是华为手机");
        }
    }
    
    .......

    如果这样的代码提供给客户端调用,那么提供者必须要将所有类的名称以及对应方法暴露给客户端。

    客户端的调试如下:

    Iphone phone1 = new Iphone();
    phone1.xxx();        // 输出:我是苹果手机
    
    Huawei phone2 = new Huawei();
    phone2.yyy();        // 输出:我是华为手机

    这样的方式非常原始,也很简单,但是代码逻辑不清晰,暴露的内容过多。

    解决的方案:

    • 抽象逻辑,提供接口
    • 2、有了接口之后

    为了减少方法调用的复杂度,也为了便于抽象跟代码管理,提供一个接口:

    public interface Phone {
        void play();
    }

    然后,将所有手机类都实现Phone接口,将暴露给客户端调用的逻辑都封装在play方法里;

    public class Iphone implements Phone{
    
      @Override
      public void play() {
          System.out.println("苹果手机");
      }
    }

    ......

    那么客户端需要知道的调用API就减少到了两种:

    1. Phone接口的信息
    2. Phone接口有哪些实现类
    Phone phone = new Iphone();
    phone.play();
    phone=new Huawei(); phone.play();

    这种方式有缺点:

    1. 客户端,必须要知道手机类的具体名字
    2. 客户端的调用,跟提供的代码是耦合的(服务端代码的更改,客户端的代码也要跟着改,比如:我们将IPhone类改为IPhonex,那么客户端那边也要跟着改)

    所以,自然产生了简单工厂的这种策略

    3、简单工厂

    在中间加一层:

    public class PhoneFactory {
        public Phone createPhone(String tag) {
            if (tag.equals("pg")) {
                return new IPhone();
            } else if (tag.equals("hw")) {
                return new Huawei();
            }else {
                return null;
            }
        }
    }

    客户端的调用

    PhoneFactory pf = new PhoneFactory();
    pf.createPhone("hw").play();
    pf.createPhone("pg").play();

    简单工厂模式,本身已经为解耦合做出来很好的方案。但是它有缺点:

    • PhoneFactory  代码跟Phone代码紧耦合
    • 每次添加/删除/修改某一个Phone ,都需要修改PhoneFactory这个类

    解决方案就是工厂方法模式

    4、工厂方法模式

    为Phone工厂,创建一个接口:

    public interface PhoneFactory {
        Phone createPhone();
    }

    如果增加了一款产品,比如是iPone,那么,只需要为iPhone创建一个工厂类就可以了

    public class IphoneFactory implements PhoneFactory {
        public phone createPhone() {
            return new IphoneX();
        }
    }
    如果再增加另外一款产品,比如Huawei,那么只需要另外一个工厂就可以了
    public class HuaweiFactory implements PhoneFactory {
        public phone createPhone() {
            return new Huawei();
        }
    }
    客户端的调用:
    PhoneFactory hwPf = new HuaweiFactory();
    hwPf.createPhone().play();
    
    PhoneFactory pgPf = new IphoneFactory();
    pgPf.createPhone().play();

    工厂方法模式,是最标准的一种工厂模式,也是应用广泛的一种模式。

    但是工厂方法模式,有一个很大的缺点:

    • 代码容易膨胀
    • 不容易反映产品与产品之间的关系

    5、抽象工厂

    public interface PhoneFactory {
        Phone createPhone();
        Usb createUSB();
        Charger createCharger();
    }

    华为手机:

    public class HuaweiPhoneFactory implements PhoneFactory {
        Phone createPhone() {
            return new HuaweiPhone();
        }
        Usb createUSB() {
            return new HuaweiUSB();
        }
        Charger createCharger() {
            return new HuaweiCharger();
        }
    }
    
    // ...
    客户端调用:
    PhoneFactory pf = new HuaweiPhoneFactory();
    pf.createPhone();
    pf.createUsb();
    pf.createCharger();
    
    // 通过一个工厂,把一个族中的相关产品全都输出来了
     
  • 相关阅读:
    python-发送邮件
    python-操作Excel表格
    PLSQL 删表 恢复
    ajax
    List<Object>
    Java String 转成 二位数组
    js-sequence-diagrams > 时序图
    Highcharts › 自由绘图
    高德地图 JS API (jsp + miniui(子页面数据返回父页面并设值) + 单个点标记 + 点标记经纬度 + 回显 + 限制地图显示范围+搜索)
    突然奋斗的开发
  • 原文地址:https://www.cnblogs.com/yl0604/p/10111771.html
Copyright © 2020-2023  润新知