原文:C#设计模式之总结篇
一、引言
C#版本的23种设计模式已经写完了,此刻也到了一个该总结的时候了。说起设计模式,我的话就对照多了。刚开始写代码的时候,有需求就写代码来解决需求,如果有新的需求,或者需求变了,我就想固然的改削本身的代码来满足新的需求,这样做觉得是理所固然的,也没觉得有什么不妥的处所。写了两年多代码,偶尔一次,风闻了设计模式,据风闻设计模式就是软件界的“独孤九剑”,学会之后就可以天下无敌,于是我就开始了我的进修之路。
想当初,我就像很多的初学编程的人一样,在面试官面前很容易说出面向东西语言的三大特征:担任,多态和封装,其实,我根柢不理解这三个词语的意思,或者说理解的很浅薄。固然也有很多观点是不清楚的,好比:OOPL(面向东西语言)是不是就是OO的全部,面向东西的设计模式和设计模式的到底有什么区别,等等相关问题。自从本身学了设计模式,很多观点变得清晰明了,干事有原则了,或者说有准则了,不像以前只是解决了问题就好,根柢不管代码写的是否合理。写的代码可以很优美了,布局更合理了,本身开始从头思考代码这个对象。
学习设计模式并不是一帆风顺的,尤其是刚开始的时候,由于本身很多观点不是很清楚,也走了很多弯路,但是通过本身的对峙,通过本身不停的看,不停的写,对模式的理解也越来越准确了。写代码不是一个很简单的工作,做任何事都是有原则的,写代码也一样,如果本身心中对做的工作没有准则,那就和无头的苍蝇一样,做与不做是一样的。写代码和写好代码是不一样的,如果要写好的代码,考虑的问题更多了,考虑不变性,扩展性和耦合性,固然也要考虑上游和下游关联的问题,让你干事的时候知道怎么做,也知道为什么这么做,这就是学习设计模式带来的好处。
好了,说了也不少了,我把我写的模式都罗列出来,每个模式都有链接,可以直接点击进入检察和阅读,但愿对大家阅读有益。
系列导航:
创建型:
C#设计模式(1)——单例模式(Singleton Pattern)
C#设计模式(2)——工厂要领模式(Factory Pattern)
C#设计模式(3)——抽象工厂模式(Abstract Pattern)
C#设计模式(4)——建造模式(Builder Pattern)
C#设计模式(5)——原型模式(Prototype Pattern)
布局型:
C#设计模式(6)——适配器模式(Adapter Pattern)
C#设计模式(7)——桥接模式(Bridge Pattern)
C#设计模式(8)——装饰模式(Decorator Pattern)
C#设计模式(9)——组合模式(Composite Pattern)
C#设计模式(10)——外不雅观模式(Facade Pattern)
C#设计模式(11)——享元模式(Flyweight Pattern)
C#设计模式(12)——代办代理模式(Proxy Pattern)
行为型:
C#设计模式(13)——模板要领模式(Template Method)
C#设计模式(14)——命令模式(Command Pattern)
C#设计模式(15)——迭代器模式(Iterator Pattern)
C#设计模式(16)——不雅察看者模式(Observer Pattern)
C#设计模式(17)——中介者模式(Mediator Pattern)
C#设计模式(18)——状态模式(State Pattern)
C#设计模式(19)——计谋模式(Stragety Pattern)
C#设计模式(20)——责任链模式(Chain of Responsibility Pattern)
C#设计模式(21)——访谒者模式(Vistor Pattern)
C#设计模式(22)——备忘录模式(Memento Pattern)
C#设计模式(23)——解释器模式(Interpreter Pattern)
二、 面向东西的设计原则
写代码也是有原则的,我们之所以使用设计模式,主要是为了适应变革,提高代码复用率,使软件更具有可维护性和可扩展性。如果我们能更好的理解这些设计原则,对我们理解面向东西的设计模式也是有辅佐的,因为这些模式的孕育产生是基于这些原则的。这些法则是:单一职责原则(SRP)、开放关闭原则(OCP)、里氏取代原则(LSP)、依赖颠倒原则(DIP)、接口断绝原则(ISP)、合成复用原则(CRP)和迪米特原则(LoD)。下面我们就分袂介绍这几种设计原则。
2.1、单一职责原则(SRP):
(1)、SRP(Single Responsibilities Principle)的界说:就一个类而言,应该仅有一个引起它变革的原因。简而言之,就是成果要单一。
(2)、如果一个类承当的职责过多,就即是把这些职责耦合在一起,一个职责的变革可能会削弱或者按捺这个类完成其它职责的能力。这种耦合会导致脆弱的设计,当变革产生时,设计会遭受到意想不到的粉碎。(敏捷软件开发)
(3)、软件设计真正要做的许多内容,就是发明职责并把那些职责彼此疏散。
小结:单一职责原则(SRP)可以看做是低耦合、高内聚在面向东西原则上的引申,将职责界说为引起变革的原因,以提高内聚性来减少引起变革的原因。责任过多,引起它变革的原因就越多,这样就会导致职责依赖,大大损伤其内聚性和耦合度。
2.2、开放*原则(OCP)
(1)、OCP(Open-Close Principle)的界说:就是说软件实体(类,要领等等)应该可以扩展(扩展可以理解为增加),但是不能在本来的要领或者类上改削,也可以这样说,对增加代码开放,对改削代码*。
(2)、OCP的两个特征: 对付扩展(增加)是开放的,因为它不影响本来的,这是新增加的。对付改削是关闭的,如果总是改削,逻辑会越来越庞大。
小结:开放关闭原则(OCP)是面向东西设计的核心思想。遵循这个原则可以为我们面向东西的设计带来巨大的好处:可维护(维护本钱小,做打点简单,影响最小)、可扩展(有新需求,增加就好)、可复用(不耦合,可以使用以前代码)、灵活性好(维护便利、简单)。开发人员应该仅对措施中呈现频繁变革的那些部分做出抽象,但是不能过激,对应用措施中的每个部分都刻意地进行抽象同样也不是一个好主意。拒绝弗成熟的抽象和抽象自己一样重要。
2.3、里氏取代原则(LSP)
(1)、LSP(Liskov Substitution Principle)的界说:子类型必需能够替换失它们的父类型。更直白的说,LSP是实现面向接口编程的根本。
小结:任何基类可以呈现的处所,子类必然可以呈现,所以我们可以实现面向接口编程。 LSP是担任复用的基石,只有当子类可以替换失基类,软件的成果不受到影响时,基类才华真正被复用,而子类也能够在基类的根本上增加新的行为。里氏代换原则是对“开-闭”原则的增补。实现“开-闭”原则的关键法式就是抽象化。而基类与子类的担任关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体法式的规范。
2.4、依赖颠倒原则(DIP)
(1)、DIP(Dependence Inversion Principle)的界说:抽象不应该依赖细节,细节应该依赖于抽象。简单说就是,我们要针对接口编程,而不要针对实现编程。
(2)、高层模块不应该依赖低层模块,两个都应该依赖抽象,因为抽象是不变的。抽象不应该依赖具体(细节),具体(细节)应该依赖抽象。
小结:依赖颠倒原则其实可以说是面向东西设计的标识表记标帜,如果在我们编码的时候考虑的是面向接口编程,而不是简单的成果实现,浮现了抽象的不变性,只有这样才切合面向东西的设计。
2.5 接口断绝原则(ISP)
(1)、接口断绝原则(Interface Segregation Principle, ISP)指的是使用多个专门的接口比使用单一的总接口要好。也就是说不要让一个单一的接口承当过多的职责,而应把每个职责疏散到多个专门的接口中,进行接口疏散。过于痴肥的接口是对接口的一种污染。
(2)、使用多个专门的接口比使用单一的总接口要好。
(3)、一个类对此外一个类的依赖性该当是成立在最小的接口上的。
(4)、一个接口代表一个角色,不该当将差此外角色都交给一个接口。没有关系的接口合并在一起,形成一个痴肥的大接口,这是对角色和接口的污染。
(5)、“不应该强迫客户依赖于它们不用的要领。接口属于客户,不属于它地址的类条理布局。”这个说得很大白了,再通俗点说,不要强迫客户使用它们不用的要领,如果强迫用户使用它们不使用的要领,那么这些客户就会面临由于这些不使用的要领的转变所带来的转变。
小结:接口断绝原则(ISP)报告我们,在做接口设计的时候,要尽量设计的接口成果单一,成果单一,使它变革的因素就少,这样就更不变,其实这浮现了高内聚,低耦合的原则,这样做也制止接口的污染。
2.6 组合复用原则(CRP)
(1)、组合复用原则(Composite Reuse Principle, CRP)就是在一个新的东西里面使用一些已有的东西,使之成为新东西的一部分。新东西通过向这些东西的委派到达复用已用成果的目的。简单地说,就是要尽量使用合成/聚合,尽量不要使用担任。
(2)、要使用好组合复用原则,首先需要区分”Has—A”和“Is—A”的关系。 “Is—A”是指一个类是另一个类的“一种”,是属于的关系,而“Has—A”则差别,它暗示某一个角色具有某一项责任。导致错误的使用担任而不是聚合的常见的原因是错误地把“Has—A”当成“Is—A”.例如:鸡是动物,这就是“Is-A”的表示,某人有一个手枪,People类型里面包罗一个Gun类型,这就是“Has-A”的表示。
小结:组合/聚合复用原则可以使系统越发灵活,类与类之间的耦合度降低,一个类的变革对其他类造成的影响相对较少,因此一般首选使用组合/聚合来实现复用;其次才考虑担任,在使用担任时,需要严格遵循里氏替换原则,有效使用担任会有助于对问题的理解,降低庞大度,而滥用担任反而会增加系统构建和维护的难度以及系统的庞大度,因此需要慎重使用担任复用。
2.7 迪米特法例(Law of Demeter)
(1)、迪米特法例(Law of Demeter,LoD)又叫最少常识原则(Least Knowledge Principle,LKP),指的是一个东西该当对其他东西有尽可能少的了解。也就是说,一个模块或东西应尽量少的与其他实体之间产生彼此感化,使得系统成果模块相对独立,这样当一个模块改削时,影响的模块就会越少,扩展起来越发容易。
(2)、关于迪米特法例其他的一些表述有:只与你直接的伴侣们通信;不要跟“陌生人”措辞。
(3)、外不雅观模式(Facade Pattern)和中介者模式(Mediator Pattern)就使用了迪米特法例。
小结:迪米特法例的初衷是降低类之间的耦合,实现类型之间的高内聚,低耦合,这样可以解耦。但是凡事都有度,过分的使用迪米特原则,会孕育产生大量这样的中介和通报类,导致系统庞大度变大。所以在给与迪米特法例时要重复权衡,既做到布局清晰,又要高内聚低耦合。
三、创建型模式
创建型模式就是用来解决东西实例化和使用的客户端耦合的模式,可以让客户端和东西实例化都独立变革,做到彼此不影响。创建型模式包孕单例模式、工厂要领模式、抽象工厂模式、建造者模式和原型模式。
3.1、单例模式(Singleton Pattern):解决的是实例化东西的个数的问题,该模式是把东西的数量控制为一个,该模式可以扩展,可以把实例东西扩展为N个东西,N>=2。好比东西池的实现。
动机(Motivate):在软件系统构建的过程中,经常有这样一些特殊的类,必需保证它们在系统中只存在一个实例,才华确保它们的逻辑正确性、以及良好的效率。如何绕过通例的结构器,供给一种机制来保证一个类只有一个实例?如果指望使用者不使用结构器来反复创建东西,这是不同错误的。这应该是类设计者的责任,而不是使用者的责任。
意图(Intent):保证一个类仅有一个实例,并供给一个该实例的全局访谒点。
具体布局图如下所示:
示例代码: