• 抽象工厂学习


    作者:caoglish
    链接:https://www.zhihu.com/question/20367734/answer/82361745
    来源:知乎
    著作权归作者所有,转载请联系作者获得授权。

    今天正好在学习抽象工厂和工厂方式,我就把我的理解写一写。

    工厂一般理解就是减少new创建对象的方式,用接口的方式来返回一个对象,而new创建的方式被封装了。然而,这个是初级认识,这不足以理解到工厂方式的真正目的。

    所以我要用我的方式帮助大家理解。

    第一部分: 抽象工厂
    一般来说,抽象工厂最简单形态也至少有4个元素:
    • 客户端(client)
    • 工厂(factory)
    • 产品A(product A)
    • 产品B(product B)

    我先用一个例子来实体说明抽象工厂是什么

    我现在有三个神枪手,他们聚在一起讨论他们玩枪的经历,
    • 神枪手1:AK47打枪最好,杀伤力大。
    • 神枪手2:沙漠之鹰最好,准。
    • 神枪手3:连弩才好,上古兵器。

    他们争论相持不下,所以决定比试一下,然后约定一个月后来鄙视。然后我们看到三个人分别去各自的工厂去购买武器。


    神射手1 去了AK47工厂,购买他们生产的武器和子弹


    神射手2 去了沙漠之鹰工厂,购买他们生产的武器和子弹

    神射手3,去了连弩工厂,购买他们生产的武器和“子弹”




    一个月后,我们看到了3个人分别拿出来以下的武器组合



    这三个人虽然用的武器不一样,但是每件武器都要做两件事


    最后,他们通过比赛谁,看哪种武器是最优秀的。


    我们回头去看看,发现虽然三个人去了不同的工厂,用了不同的武器,用了不同的子弹,但是他们的相似之处太多,可以抽象出来。抽象出来的关系框架就是抽象工厂模式

    • 武器工厂生产武器
    • 武器工厂生产武器所用的子弹
    • 武器可以装载子弹
    • 武器可以射击子弹
    • 神射手装载子弹
    • 神射手射击子弹

    那么把关系画出来就是:

    然后抽象一下成工厂模式就是:


    图画出来了,然后我们要如何理解抽象工厂模式. 过去人们都是从工厂开始解释,其实我个人觉得,倒过来讲反而更好理解。而理解抽象工厂模式的关键在于如何理解“产品之间特定关系”。

    1. 用户要调用产品之间的这个特定关系
    2. 这个特定关系只有产品A和产品B之间才有,所以我们需要产品A和产品B
    3. 要获得产品A和产品B,我们要去生产这个产品A和产品B的那个工厂,叫工厂生产这个产品A和产品B

    那么用例子来说,就是:

    1. 神枪手喜欢装载子弹和射击的感觉(他们就是喜欢这个,只要有武器符合这个条件就行)
    2. 那么他们就是需要武器(枪或者连弩)和子弹,这个武器是可以装载相应子弹和射击相应子弹的
    3. 他们可以去特定工厂(ak47工厂或者连弩工厂)要求购买武器和相应子弹、

    所以理顺抽象工厂的特点是什么?就是如下几个特点:

    • 工厂是独立的(独立的类)
    • 工厂是生产一整套有产品的(至少要生产两个产品),这些产品必须相互是有关系或有依赖的
    • 工厂是可以抽象的,工厂生产是可以抽象的,就是可以建模,用类来模拟
    • 产品是可以抽象的,产品关系是可以抽象的
    • 客户端是用来调用并理顺这些产品之间的关系(或指定工作流程)
    • 不同工厂生产出的产品实例之间是不接触的,这个是靠客户端来封装实现的。
    用一个例子来解释一下最后一条“不同工厂生产出的产品实例之间是不接触的,这个是考客户端来封装实现的”。
    一个射击学员刚入门,听到射击老师说射击的几个要素: 武器,子弹,武器装载子弹,武器打出子弹。这个学员跃跃欲试,就跑到Ak47工厂买了枪,然后跑到沙漠之鹰工厂买了子弹,AK47装载沙鹰子弹,然后打出。学员卒。

    老师听说后,为了避免这个悲剧发生,承包了武器和子弹购买,要用AK47就必须在AK47工厂购买AK47和AK47子弹,保证了AK47加载沙漠之鹰子弹这样的悲剧发生了。
    这就是客户端加载工厂实例后,保证只使用这个工厂的生产的产品和产品之间的关系,确保不和其他工厂的产品实例进行接触。

    最终当我们调用客户端的行为时候,只要让客户端“加载”实例化的特定工厂,返回结果就是这个“特定工厂”所加工出来的“特定产品”的“特定关系”方法的结果了。


    所以,当产品非常多的时候,产品之间关系又非常复杂,但却又可以进行抽象的时候,就是使用抽象工厂模式最好的时候了。

    以上就是抽象工厂模式的个人理解


    --------

    第二部分: 工厂方法


    工厂方法就两个元素:

    • creator(创建者)
    • product(产品)

    而工厂方法就是一个创建者这个类的一个方法而已,这个方法就是用来封装产品的创建。


    第三部分: 抽象工厂 和工厂方法的不同点


    我从一下几个方面来理解抽象工厂和工厂方法不同点

    • 抽象工程关键在于产品之间的抽象关系,所以至少要两个产品;工厂方法在于生成产品,不关注产品间的关系,所以可以只生成一个产品。

    • 抽象工厂中客户端把产品的抽象关系理清楚,在最终使用的时候,一般使用客户端(和其接口),产品之间的关系是被封装固定的;而工厂方法是在最终使用的时候,使用产品本身(和其接口)。
    抽象工厂更像一个复杂版本的策略模式,策略模式通过更换策略来改变处理方式或者结果;而抽象工厂的客户端,通过更改工厂还改变结果。所以在使用的时候,就使用客户端和更换工厂,而看不到产品本身。

    工厂方法目的是生产产品,所以能看到产品,而且还要使用产品。当然,如果产品在创建者内部使用,那么工厂方法就是为了完善创建者,从而可以使用创建者。另外创建者本身是不能更换所生产产品的。


    • 抽象工厂的工厂是类;工厂方法的工厂是方法。
    抽象工厂的工厂类就做一件事情生产产品。生产的产品给客户端使用,绝不给自己用。
    工厂方法生产产品,可以给系统用,可以给客户端用,也可以自己这个类使用。自己这个类除了这个工厂方法外,还能有其他功能性的方法


    其实仔细想想,这个两个模式是有交集的,在极端的情况下,这两个模式其实是一样的。所以可以这样理解
    • 给工厂方法模式加一个客户端,除了客户端都不用这个创建者。这个时候创建者就是工厂类了。(单一产品的特定关系这个时候就是没有关系)
    • 抽象工厂模式中,在客户端内部编程时候,就可以把工厂类当作创建者。
  • 相关阅读:
    在客户端模拟调用srv和topic
    直流电机测试标准
    vue项目修改host实现地址代理,实现一键登录
    小程序 日期格式化
    ES6学习笔记之async函数
    ES6学习笔记之promise
    ES6学习笔记之箭头函数
    ES6学习笔记之var,let,const
    axios post后台接收不到参数
    vue-cli2配置scss遇到的各种坑
  • 原文地址:https://www.cnblogs.com/ZengYunChun/p/6088346.html
Copyright © 2020-2023  润新知