• 工厂模式


    工厂模式

    代码编写出来是为了给别人 (client) 调用的:

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

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

    1 最原始的方式

    比如说,有一系列的代码,是用来创建不同品牌的手机。代码是这样的:

    public class Iphone {
        public void mypg () {}
    }
    public class Huawei {
        public void myhwi () {}
    }
    public class Lennovo {}
    public class Xiaomi {}
    public class Vivo {}

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

    客户端的调用示例如下:

    Iphone pg = new Iphone();
    phone1.mypg();
    
    Huawei hw = new Huawei();
    phone2.myhw();

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

    解决的方案:

    • 抽象逻辑,提供接口

    2 有了接口之后

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

    public interface Phone {
        void play();
    }

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

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

    1. Phone 接口的信息
    2. Phone 接口有哪些实现类

    调用的逻辑就变简单了:

    Phone phone1 = new Iphone();
    phone1.play();
    
    Phone phone2 = new Lianxiang();
    phone2.play();
    
    Phone phone3 = new Xiaomii();
    phone3.play();

    这种方式有缺点:

    1. 客户端,必须要知道手机类的具体名字
    2. 客户端的调用,跟提供的代码是耦合的

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

    3 简单工厂

    在中间加一层:

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

    客户端的调用:

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

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

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

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

    4 工厂方法模式

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

    public interface GCIphoneFactory {
    Phone createPhone();
    }

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

    public class IphoneFactory implements GCIphoneFactory {
        @Override
        public Phone createPhone() {
            return new IPhone();
        }
    }

    如果再增加另外一款产品,比如 Huawei,那么只需要另外一个工厂就可以了:

    public class HuaweiFactory implements GCIphoneFactory {
        @Override
        public Phone createPhone() {
            return new Huawei();
        }
    }

    客户端的调用:

    GCIphoneFactory gc = new HuaweiFactory();
    gc.createPhone().play();
            
    GCIphoneFactory pg = new IphoneFactory();
    pg.createPhone().play();

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

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

       每增加一个产品,相应的也要增加一个子工厂,加大了额外的开发量。
     
  • 相关阅读:
    C# WinForm下,隐藏主窗体,只在进程管理器中显示进程,在任务栏,状态栏都不显示窗体的方法
    C#全能数据库操作类及调用示例
    多个汇总列转换为行记录 mssql
    Oracle 10g创建数据库 用户等基本操作
    Jquery基本选择器 层次选择器 过滤选择器 表单选择器使用示例 带注释
    SQL与ORACLE的外键约束级联更新和删除
    C# 屏幕监控 自动截屏程序 主窗体隐藏,仅在进程中显示
    图文讲解VS2010程序打包操作 安装卸载
    查表法按日期生成流水号 mssql
    给DataTable添加主键 几何级提升Select筛选数据的速度
  • 原文地址:https://www.cnblogs.com/guapishuo/p/10102010.html
Copyright © 2020-2023  润新知