大话设计模式

好的技术文章应该让读者更自信而不是更自卑

淺唱寂寞╮ 提交于 2019-12-27 00:44:49
  今天朋友给我微博留言,说我的《大话设计模式》被拍砖了。果不其然,确实是在《 放过设计模式吧 》的评论 第8条 中有。还好博主并没有在博文中点名我的书,还算是留了点客气。不过如此轰动的一篇博文(博客园编辑首页推荐),但却传达了一些让初学者困惑的信息——我们初学者在不知道对错的情况下到底还要不要写设计模式的心得文章?针对此我写了一篇吐槽的博文,说说我的想法。 我对《放过设计模式吧》文中所说的技术内容绝大部分认同,这点需要事先明确。作者谈了很多他对设计模式的理解和现在网上很多初学者误用设计模式的现象,这些都是可取的。比如将GoF的《设计模式:可复用面向对象软件的基础》应该翻译为《面向对象设计23招》这样的趣解,比如说策略模式和桥接模式的根本不应该因为UML图的类似而就认为他们容易混淆,他们根本就是讲了两回事等。作者对设计模式理解的高度应该是足够了。 但阅读完毕后,作为一个读者,特别是站在一个初学者的角度,这篇文章却让我感觉很压抑,有一种“他对设计模式理解得这么深,让我都不敢再去讨论设计模式了,真心怕挨骂呀!”的感觉。我不知道别的读者是否是这样,不过对于阅读本文的那些非擅长设计模式的读者来说,应该有类似的想法。 我一直有一个观点:“ 好的技术文章应该让读者更自信而不是更自卑 ”。自信是指读者读完之后,感觉很有收获,心情愉悦,有兴趣可以试着照做。自卑是指读完之后,甚为不爽,这个看不懂

大话设计模式:解释器模式

倖福魔咒の 提交于 2019-12-26 01:23:11
一、什么是解释器模式 定义一个语言,定义一个解析器,解析器解释语言 某种繁复的输入可有一定规律抽象为行为,定义语言,使用解释器将这些语言转换为行为,解释器模式提供了评估语言的语法或表达式的方式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文。 UML图 AbstractExpression : 抽象表达式,定义一个抽象方法接收输入 TerminalExpression : 实现与文法中的元素相关联的解释操作,通常一个解释器模式中只有一个终结符表达式,但有多个实例,对应不同的终结符。 NonterminalExpression :——非终结符表达式,文法中的每条规则对应于一个非终结表达式,具体到我们的例子就是加减法规则分别对应到AddExpression和SubExpression两个类。非终结符表达式根据逻辑的复杂程度而增加,原则上每个文法规则都对应一个非终结符表达式。 Context :上下文,通常包含各个解释器需要的数据,或是公共的功能。 二、适用场景 当有一个语言需要解释执行,并且你可以把该语言中的句子表示为一个抽象的语法树时,比如正则表达式,比如根据用户输入的公式进行加减乘除四则运算 三、优缺点 优点 扩展性,修改语法规则只需要修改相应的非终结符就可以了,若扩展语法,只需要增加非终结符类就可以了。 缺点 解释器模式会引起类的膨胀

大话设计模式之装饰者模式

[亡魂溺海] 提交于 2019-12-24 04:02:44
1、定义 Decorator模式(别名Wrapper):动态将职责附加到对象上,若要扩展功能,装饰者提供了比继承更具弹性的代替方案。 2、意图: 动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。 3、设计原则: 1. 多用组合,少用继承。 利用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为。然而,如果能够利用组合的做法扩展对象的行为,就可以在运行时动态地进行扩展。 2. 类应设计的对扩展开放,对修改关闭。 4、要点: 1. 装饰者和被装饰对象有相同的超类型。 2. 可以用一个或多个装饰者包装一个对象。 3. 装饰者可以在所委托被装饰者的行为之前或之后,加上自己的行为,以达到特定的目的。 4. 对象可以在任何时候被装饰,所以可以在运行时动态的,不限量的用你喜欢的装饰者来装饰对象。 5. 装饰模式中使用继承的关键是想达到装饰者和被装饰对象的类型匹配,而不是获得其行为。 6. 装饰者一般对组件的客户是透明的,除非客户程序依赖于组件的具体类型。在实际项目中可以根据需要为装饰者添加新的行为,做到“半透明”装饰者。 7. 适配器模式的用意是改变对象的接口而不一定改变对象的性能,而装饰模式的用意是保持接口并增加对象的职责。 5、实现图 6、具体实例 装饰模式结构图 Component是定义一个对象接口

大话设计模式--建造者模式 Builder -- C++实现实例

点点圈 提交于 2019-12-23 21:33:37
1. 建造者模式,将一个复杂对象的构建与它的表示分离, 使得同样的构建过程可以创建不同的表示。 用户只需要指定需要建造的类型就可以得到他们,而具体建造的过程和细节就不需要知道了。 关键类Director,用它来控制建造过程,用它来隔离用户与建造过程的关联。 适用场合主要是用于创建一些复杂的对象, 这些对象内部的构建间的建造顺序通常是稳定的,但对象内部的构建通常面临着复杂的变化。 在创建复杂对象的算法应该独立于该对象的组成部分以及他们的装配方式适用的模式。 建造者模式的好处就是使得建造代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所以若需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了。 实例骨架: product.h product.cpp #ifndef PRODUCT_H #define PRODUCT_H #include <iostream> #include <list> #include <string> using namespace std; class Product { public: Product(); void addPart(string part); void show(); private: list<string> *parts; }; #endif // PRODUCT_H #include "product.h"

《大话设计模式》——简单工厂模式(Python)

给你一囗甜甜゛ 提交于 2019-12-23 04:12:07
简单工厂模式(Simple Factory Pattern) : 是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类. 例: 使用Python设计一个控制台计算器,要求输入两个数和运算符号,得到运算结果。 1. 初学者写法 class Operation ( object ) : def __init__ ( self ) : pass def conver_strNumber ( self , strNumber ) : ''' 将字符串格式的数字,转化成对应格式的数字 :param strNumber: :return: ''' if '.' not in strNumber : return int ( strNumber ) else : return float ( strNumber ) def op ( self , strNumberA , strNumberB , strOperate ) : if strOperate == '+' : return self . conver_strNumber ( strNumberA ) + self . conver_strNumber ( strNumberB ) elif strOperate == '-' : return self . conver_strNumber (

策略模式 -- 大话设计模式

牧云@^-^@ 提交于 2019-12-22 08:20:54
在今天,读书有时是件“麻烦”事。它需要你付出时间,付出精力,还要付出一份心境。--仅以《大话设计模式》来祭奠那逝去的…… 策略模式就是用来封装算法的。实践中,我们发现可以用它来封装几乎任何类型的规则,只要分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。 1.商场促销活动   实现商场促销活动,正常收费、满300返100和打8折活动   首先我们定义一个收费抽象类,包含一个收取现金抽象方法 /// <summary> /// 收费抽象类 /// </summary> public abstract class Fee { /// <summary> /// 收取现金抽象方法 /// </summary> public abstract double AcceptCash(double money); }   然后实现我们需要的算法:正常收费和打折收费,让其继承收费抽象类,重写AcceptCash方法实现不同的收费算法(如果我们以后要增加其他收费方法,只需要新增一个继承Fee收费抽象类的子类,实现其收费算法,而无需变动已经写好的算法) /// <summary> /// 正常收费 /// </summary> public class FeeNormal : Fee { public override double AcceptCash

大话设计模式-装饰模式

孤街醉人 提交于 2019-12-20 14:06:46
装饰模式 动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。 装饰模式结构演示 组件类:Component Component是定义一个对象接口,可以给这些对象动态地添加职责。 abstract class Component{ public abstract void Operation(); } 具体组件类:ConcreteComponent ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责。 class ConcreteComponent : Component{ public override void Operation() => Console.WriteLine("具体对象的操作"); } 装饰抽象类:Decorator 继承了Component,从外类来扩展Component类的功能,但对于Component来说是无需知道Decorator的存在的。 abstract class Decorator:Component{ protected Component component; //设置组件 public void SetComponent(Component component) => this.component = component; //重写方法为调用组件的原方法 public

12 大话设计模式C++实现之外观模式

筅森魡賤 提交于 2019-12-20 00:40:54
/* 外观模式: 为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这一接口使得这一子系统更加容易使用 其中外观类需要了解所有子系统的方法或属性,对它进行组合,以备外界调用。 何时使用外观模式: 首先,在设计阶段初期,应该有意识的将不同的两个层分离,比如经典的三层架构,就需要考虑在数据访问层、业务逻辑层和表示层的层与层之间建立Facade, 这样可以为系统提供一个简单的接口,使得耦合度大大降低,其次,在开发阶段,子系统往往因为不断地重构烟花而变得越来越复杂,大多数的模式使用时也都会产生很多很小的类, 这是好事,但也给外部调用他们的用户程序带来了使用上的困难。增加外观Facade可以提供一个简单的接口,减少他们之间的依赖。 第三,在维护一个遗留的大型系统时,可能这个系统已经非常难以维护和扩展了,但因为它包含非常重要的功能,新的需求开发必须依赖他。此时外观模式是非常适合的。 可以为系统开发一个外观facade类,让新系统与facede对象交互,facade与遗留代码交互所有复杂的工作。 */ #include<iostream> #include<string> using namespace std; class A { public: void Method1() { cout << "A" << endl; } }; class B { public: void

大话设计模式---代理模式

走远了吗. 提交于 2019-12-18 15:08:18
     代理模式:为其他对象提供一种代理以控制对这个对象的访问。   代理模式应用: 远程代理,也就是为一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实。 虚拟代理,根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真实对象。 如打开一个很大的HTML网页,虚拟代理替代真实图片。 安全代理,用来控制真实对象访问时的权限。 一般用于对象应该有不同的访问权限。 智能指引,是指当调用真实的对象时,代理处理另外一些事。 如第一次引用一个持久对象时,将它装入内存。 来源: https://www.cnblogs.com/nixuebing/p/4191193.html

【大话设计模式】——代理模式

大憨熊 提交于 2019-12-16 14:37:22
一、概念   在真实生活中,我们每一个人的能力是有限的,总有一些事情让我们无奈,我们可以找别人帮忙,这个人叫来帮助我们的代理商。让我们看一下代理模式的概念:    代理模式(Proxy): 为其它对象提供一种代理以控制对这个对象的訪问。 二、UML图 Subject(抽象角色): 定义了RealSubject和Proxy的共用接口。这样就在不论什么使用RealSubject的地方都能够使用Proxy. RealSubject(真实角色): 定义了Proxy所代表的真实实体。 Proxy(代理角色): 保存了一个引用使得代理能够訪问实体,并提供一个与Subject的接口同样的接口,这样代理就能够用来取代实体。 RealSubject和Proxy都继承了Subject抽象类的方法。Proxy和RealSubject的关系是关联关系。体如今代码上,RealSubject类中书写详细的方法,Proxy去调用RealSubject中的方法。Proxy和RealSubject共同实现Subject的接口。 三、实例解析   有的时候,一些突发事件蹦出来想要打乱了我们的计划,却又正好赶上我们有更加重要的事情要亲自去做,那这件紧急不重要的事情怎么办呢?假设能够的话。让别人取代我们完毕。   这就要用到我们的代理了。XX去帮我打个水吧,XX去帮我取个快递吧~ 以下是应用了代理模式的代码: using