热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[学习笔记]设计模式之FactoryMethod

在上篇笔记AbstractFactory设计模式中,时の魔导士创建了一系列的FoodFactory,并教会了其中一名霍比特人theCook如何去createFood。于是,白雪

写在前面

在上篇笔记Abstract
Factory设计模式中,时の魔导士创建了一系列的FoodFactory,并教会了其中一名霍比特人theCook如何去createFood。于是,白雪公主和7个小霍比特人终于能填饱肚子了。但是,美丽的童话世界中一定有着危险潜伏。这时,我们需要有一名霍比特人勇敢地站出来守护善良的公主和她的小伙伴们。很好,就让我们叫他theWarrior,一位武器大师:精通匕首、剑、弓、魔杖甚至AK47……。正因如此,我们需要一个武器工厂生产一整套的装备供他使用。回顾上篇笔记的内容,时の魔导士自然想到抽象工厂的好主意,我们可以有SwordFactory,
DaggerFactory,
BowFactory......但是有个问题,createWeapon并不能像createFood那样将制作过程硬编码,因为theWarrior会需要不同的武器组合,比如英勇的战士一般配一把利剑和坚固的盾牌,或者像精灵王子莱格拉斯(出自电影:霍比特人2)那样带2把匕首和弓箭。怎么样才好呢?当然>Factory Method!其实在抽象工厂篇中,我们已经用到>Factory
Method
来实现抽象工厂了。现在让我们来看看具体的内容吧。


要点梳理



  • 目的分类

    •  对象创建型模式

  • 范围准则

    • 类(该模式处理类和子类之间的关系,这些关系通过继承建立,是静态的,在编译时刻便确定下来了)

  • 主要功能

    • 定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类

  • 适用情况

    • 当一个类不知道它所必须创建的对象的类的时候

    • 当一个类希望由它的子类来指定它所创建的对象的时候

    • 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候参与部分

  • 参与部分

    • >Product:定义工厂方法所创建的对象的接口

    • ConcreteProduct:实现 >Product接口

    • >Creator:声明工厂方法,该方法返回一个Product类型的对象。 >Creator也可以定义一个工厂方法的缺省实现,它返回一个缺省的 >ConcreteProduct对象;可以调用工厂方法以创建一个 >Product对象

    • >ConcreteProduct:重定义工厂方法以返回一个 >ConcreteProduct实例

  • 协作过程

    • >Creator依赖于它的子类来定义工厂方法,所以它返回一个适当的 >ConcreteProduct实例

  • UML图例

 bubuko.com,布布扣src="https://img8.php1.cn/3cdc5/15d29/bdf/77e738d1358857a0.jpeg"
>


示例分析 - 强大的武器工坊

时の魔导士仔细思考了一番,决定先建造一座充满魔法的WeaponFactory,通过引入Factory
Method
,以使得其具体的子类可以选择这些构件,装配出一套适合theWarrior的武器。我们来看一下这个示例:



1 class WeaponFactory {
2 public:
3 void getWeapon(WeaponSuite* suite);
4
5 //Factory method:
6 virtual Weapon* createWeapon() { return 0; }
7 }
8
9 void WeaponFactory::getWeapon(WeaponSuite* suite) {
10 Weapon* w = createWeapon();
11 suite->add(w);
12 }

于是我们可以引入一个名为『战士的荣耀』的长剑工厂(Kimi: 是不是很酷!……):


1 class HonorOfFighter : public WeaponFactory {
2 public:
3 HonorOfFighter();
4 Weapon* createWeapon() { return new Sword(); }
5 }

或者一个名为『卫士的信仰』的盾牌工厂,等等等等:


1 class BliefOfDefender : public WeaponFactory {
2 public:
3 BliefOfDefender();
4 Weapon* createWeapon() { return new Shield(); }
5 }

为了更清楚地表示上面所说的模型,让我们来看看UML图:

bubuko.com,布布扣src="https://img8.php1.cn/3cdc5/15d29/bdf/aaae4467ecc204b2.jpeg"
>

哈哈,这下勇敢的霍比特人就能通过拜访不同的工厂来自由获取自己的战斗武器了。


特点总结

我们来总结下工厂方法模式的特点:



  1. 工厂方法不再将与特定应用有关的类绑定到我们的代码中。代码仅处理Product接口;因此它可以与用户定义的任何ConcreteProduct类一起使用。

  2. 为子类提供挂钩(hook)。用工厂方法在一个类的内部创建对象通常比直接创建对象更灵活。

  3. 潜在缺点在于我们可能仅仅为了创建一个特定的ConcreteProduct对象,就不得不创建Creator的子类。

当然,如我最早的笔记中所说,设计模式固然重要,但>绝不可照本宣科。不同的设计模式之间往往存在着相互依赖,相辅相成的微妙关系。正如前篇中的>Abstract Factory,通常会使用>Factory Method来实现,当然也可以用Prototype,只是我们暂时还没有涉及。

抽象工厂模式和工厂方法模式从设计模式的角度来讲,的确是存在差异的。但是在我的这两篇笔记中,有的朋友可能会觉得我的示例中都同时存在着抽象工厂模式和工厂方法模式。没错,但是请还是根据文章的内容,辩证地来看待。


写在最后

今天的笔记就到这里了,欢迎大家>批评指正!如果觉得可以的话,好文>推荐一下,我会非常感谢的!

[学习笔记]设计模式之Factory Method,布布扣,bubuko.com


推荐阅读
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 在project.properties添加#Projecttarget.targetandroid-19android.library.reference.1..Sliding ... [详细]
  • 在开发中,有时候一个业务上要求的原子操作不仅仅包括数据库,还可能涉及外部接口或者消息队列。此时,传统的数据库事务无法满足需求。本文介绍了Java中如何利用java.lang.Runtime.addShutdownHook方法来保证业务线程的完整性。通过添加钩子,在程序退出时触发钩子,可以执行一些操作,如循环检查某个线程的状态,直到业务线程正常退出,再结束钩子程序。例子程序展示了如何利用钩子来保证业务线程的完整性。 ... [详细]
  • ps:写的第一个,不足之处,欢迎拍砖---只是想用自己的方法一步步去实现一些框架看似高大上的小功能(比如说模型中的toArraytoJsonsetAtt ... [详细]
  • linux location root访问文件夹404_Linux下yum安装PHP7.2+Nginx+Mysql
    一.安装NGINX1.先查看是否安装了第三方软件库:yumlistinstalled|grepepel-release或rpm-qepel-release如果已经安装 ... [详细]
  • php自动部署笔记,php自动化部署工具
    本文目录一览:1、码云gitee利用PHP脚本拉取实现自动部署(可用于生产环境) ... [详细]
  • linux内核网络钩子函数使用,Linux内核IOCTL网络控制框架实现实例分析
    4.6、inet_ioctl函数由于inet_ioctl函数内容分支很多,但功能、处理不难理解,所以我把一些不常见的内容都省去,挑简单重要的说,完全在于抛砖引玉:staticint ... [详细]
  • iOS安全攻防(二十四):敏感逻辑的保护方案(1)Objective-C代码容易被hook,暴露信息太赤裸裸,为了安全,改用C来写吧!当然不是全部代码都要C来写,我指的是敏感业务逻 ... [详细]
  • 查看全部数据库表参照地址:https:www.cnblogs.comzhoulixiangblogp12078724.html本文所用数据库表:prod_idvend_idprod ... [详细]
  • PHP设置MySQL字符集的方法及使用mysqli_set_charset函数
    本文介绍了PHP设置MySQL字符集的方法,详细介绍了使用mysqli_set_charset函数来规定与数据库服务器进行数据传送时要使用的字符集。通过示例代码演示了如何设置默认客户端字符集。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
author-avatar
前前后后zzyyix
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有