设计模式总结

前言


  设计模式是一套被反复使用,多数人知晓,关于代码设计的经验总结。关于设计模式我的感受有几点:
  1.见得比较少,对设计模式可以使用的地方,还不是很清楚,我想这是一条充满惊喜的路。
  2.了解了设计模式的内容,有了一定的理解,和之前学习最大的不同之处就是面向对象的设计方法,使得我们设计的软件更加具有灵活性,可维护性好,复用性强。

  3.更加清楚的认识到现在的学习真的才刚刚开始,自己要好好珍惜现在的学习时光。


总体认识


  学习了设计模式之后,发现我们一定要紧紧围绕着设计模式的基本原则来设计,对于各个模式的理解,大致可以分为三大类:建造者模式,行为型模式,结构型模式。我感受到的是设计模式使得对象和类之间的耦合度降低,充分提高代码的扩展性和复用性。以下是一个总体的认识:



设计原则


1单一职责

   一个类有一个职责,如果一个类的职责过多的话,等于把这些职责耦合在一起,一个职责的变化可能会影响到这个类其他职责的完成情况。


2开放-封闭

  对扩展开放,对修改关闭。这是面向对象设计的核心,遵循这个原则可以使软件开发可维护,可扩展,可复用,灵活性大。我认为修改会导致在没有完全了解软件结构的情况下,会错上加错,当然,也没有绝对的封闭,这时就需要做适当的预判了吧。


3里氏代换

  子类型必须完全替换父类型。为什么这么说呢?子类型继承父类,在用到父类的地方,必须能够完全代表父类的角色去使用,这样才可以做到在不需要修改的前提下进行扩展。


4依赖倒转

  1.高层模块不依赖于低层模块,两个都依赖于抽象。
  2.抽象不该依赖于细节,细节依赖于抽象。

  面向对象的优点是可维护,可复用,可扩展灵活性好。那么我认为最关键的就是抽象了,这一步提高了,对于代码的复用我们可以很好的做到吧。


5迪米特法则

 最少知识法则,如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的交互作用,这时可以通过第三方参与完成一个类调用另一个类的操作。


6合成/聚合复用

  当我们用到关系的时候,常常想的就是继承,当然这也是一种办法,不过继承就意味着关系很紧密,父类一旦变化,子类就会跟着变化,这时我们要用到合成/聚合关系。合成:整体部分的关系,部分离开整体没有存在的意义了。聚合:当部分离开整体仍然有独立存在的意义。


设计模式



一 建造者模式


1简单工厂

  相当于一个模子,根据已经可以正常实现功能的原样(已经封装好的一个可以独立工作的类),刻出新的样品来。这个工厂是如何实现的呢?通过工厂中的一些特定参数,来指定工厂生产。

特点:

  1.专门抽象出一个类只进行实例化,耦合度降低了。
  2.违背了开放封闭的原则:因为我们如果想要增加一种产品的话,需要增加一个类,同时还要在工厂中进行修改,添加一个参数。
  如下是UML图,(声明:以下所有的图是根据自己的理解,对教材中的原图进行相应的改动或简化,如有不足请多指点。)



2工厂方法

  工厂方法:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

  工厂方法VS简单工厂

  工厂方法是简单工厂的解耦和,怎么说呢,简单工厂里根据参数来确定要new的类,工厂的方法,直接把参数要确定的内容给独立开来了,成为工厂方法的子类,有时候直接调用(跟简单工厂的方法类似)这样实现优化简单的工厂的开关原则。
  工厂方法是简单工厂的抽象和优化,但是也不是最优的,需要改动。 以下是简单工厂的uml图:

3抽象工厂

  抽象工厂,在工厂方法的基础上,再抽象出来一个可以称之为父类的更加抽象的工厂,同时可以new的类也不是单单具体的类了,这些具体的类还可以再抽象。

特点:

  1.充分体现了依赖倒转原则,和开闭原则。
  2.增加新产品的时候会有在多处有变动,同时需要在具体工厂做添加工作。
  3.可以用到反射。
  以下是uml图,画的很简单:



缺点:

  增加一个产品时,需要在工厂方面:增加抽象工厂的方法,具体工厂的方法,在抽象类方面:增加该产品操作的抽象类,增加具体类。


4建造者

  当我们构建一个东西时,他的内部结构很复杂,我们用建造者模式来做,将构建所需的方法全部封装在一个抽象类,我们再去继承这个类,这样不会使我们面对复杂的过程少一些步骤。
建造者模式是将内部复杂的建造过程和表现分离,这时就需要一个指挥者,你需要造什么,就跟建造者说,这样达到了更好的分离。
以下是uml图:



5原型模式

  用原型克隆出新的东西,其实对原型的一个实例化。这里原型可以是一个抽象的类,可以创建新的东西的方式就喜欢将其实例化。

说明:

  .Net的库中对于克隆,写好了一个接口ICloneable,可以直接用。调用的方法是:MemberwiseClone()

以下是uml图:



6单例

  一个类只有一个实例,并提供一个访问它的全局访问点。

特点:

  一个类只有一个功能,使得我们对这个功能修改时,需要参与的修改的类比较少。



二 结构型模式


7装饰模式

  动态的给一个对象添加一些额外的职责,从增加功能的角度来看,比生成子类更为灵活

优点:

  把类中的装饰功能从该类中搬移出去,这样可以简化原有的类。



8代理模式

  代表别的对象去执行操作,我认为这样做的目的可以为原来的对象减负。这里真正的操作,是代理者在操作。
以图说明:



9外观模式

  外观模式,对一组系统,提供统一的管理界面,这样我们需要访问某一系统的时候,只要访问这个界面,就可以达到我们的目标。

优点:

  1.方便对子系统的统一调用,为访问提供一个简单的接口。
  2.减少子系统之间的耦合。



10适配器模式

  将一个类的接口转换成用户所需要的接口,这时用到适配器,来做转换工作,解决接口的不兼容性。



11组合模式

  用户对单个对象和组合对象的使用具有一致性,在我们遇到整体和部分层次问题是,可以使用。我们可以用一个接口或者抽象类,让整体和部分都去实现接口,这样他们的功能在外部看来就是一致的了。

效果:

  想让整体部分一致对待,或者说单个对象和组合对象一致对待。用户不用考虑内部。



 

12桥接模式

  将抽象部分与它的实现部分分离,使他们都可以独立的变化。 避免了继承的高耦合性。
既然是桥接,就有桥的意思,那他们之间是如何联系的呢,联系方式是一种原则,组合/聚合原则。

优点:

  很多时候我们可以用子类去继承父类,从而去使用父类的东西,或是去实现一个接口,这种继承的关系是一种强耦合的关系,一旦父类变化,子类就需要跟着变化。桥接模式正好进行了一个解耦和的作用。



13 享元模式

  有一个享元超类,泛化出具体的子类,这时有一个享元工厂,使得享元类更好的被共享,当用户需要使用这个享元类实例的时候,工厂可以自动返回一个已有的实例,或者创建一个没有(如果不存在的话)。

目的:

  减少存储空间。对于没有的只实例化一次,对于已有的对象不用再实例,只是索引的不同(我认为)


三 行为型模式


14策略模式

  策略模式,对不同的算法进行了封装,具体的算法之间耦合度降低,同时可以相互替换。而这个相互替换,就是下图中context的作用,它的存在可以调用具体的算法。



15模板方法

  定义一组操作的基本框架,将他的一些步骤延迟到子类中qu 实现。这个基本框架我们可以理解为一个模板,子类可以使用这个模板,并可以增加一些自己的独特性。
除了更详细的实现层次上不同外,其他的过程或步骤是一致的,我们可以用模板方法来处理。

优点:

  把不变行为搬移到超类,去除子类中的重复代码来实现它的优势。



16观察者模式

  定义了一种一对多对应关系,多个观察者可以同时监听一个对象,当这个对象发生变化时,会通知观察者,观察者会做出具体的反应。

条件:

  什么时候需要使用观察者模式呢,当一个对象状态的改变会影响到其他对象的改变时,就需要用到观察者模式,观察者是抽象依赖抽象,我们不需要具体的对象相互作用。观察者模式是一个解耦合的过程,我们做的是让抽象依赖于抽象。

不足:

  对于一个接口中的方法,对不同的对象,我们不能让他们直接实现这个方法,那么我们就要间接的去实现,那么如何实现呢?




事件委托

  委托事件可以把方法装上,装上了之后就与该方法具有完全相同的行为。委托方法的使用,可以像其他任何方法一样可以有参数和返回值。一个委托可以装上多种方法。


注意

  委托事件所搭载的方法,必须具有相同的原形和形式,也就是要有相同的参数和返回值类型。


17状态模式

  状态模式,当对象的状态发生改变时,他的行为会做出相应的变化。
同时还有一个context联系上下文,将跟状态有关的东西放在一起,维护具体的状态类。同时状态需要改变时,可以转换。

优缺点:

1.将同一状态的行为封装在一起,很容易进行扩展。同时各个状态之间的耦合度相应降低。
2.不同的状态在转换的时候,还是有些交互。我认为应该可以优化的。



18备忘录模式

  我们可以回到上一个时刻的状态的一种模式,对于这种情况的实现,我们可以有一个存储箱,将自己现在的状态存在里面,随着时间的流逝,自己(发起人)想要穿越了可以把存储箱的东西给了现在的自己,那就变成了过去的那个状态,这时需要提一点的是有一个管理员来保管存储箱,为啥这么做呢,便于封装,我们获得前一个时期的状态,只要与管理员联系就可以了,而不必对存储箱的结构了解。



19命令模式

  当我们有请求的时候,可以通过执行者完成这个请求,如果直接让执行者执行这个请求,那么类之间的耦合度就会加大,用一个命令用来解耦,使得请求和执行者的分离。
  将请求封装成一个对象,这个请求可以激活一个命令~不同的请求可以对用户形成参数化


20职责链模式

  申请可以让一个或多个对象都有机会进行处理,避免请求的发送者和接收者之间的耦合关系太强,同时也可以让这个请求得到处理。那么如何实现过个对象都可以处理这个请求,我们在对象之间绑上了联系,这样的话,如果该对象处理不了,就把请求抛给他的上级去处理。

优缺点:

  1.请求可以被处理,而不用考虑链的结构。
  2.考虑不全面的时候这个请求可能最终都得不到处理。



21中介者模式

  将一系列的对象交互,封装在一个中介者中,这样可以避免各个对象之间直接的相互作用,起到一个解耦和。

适用:

一组对象他们的定义良好,但是之间的信息交互复杂。

优缺点:

  1.对象之间的耦合度降低,只是和中介联系,不用对象之间联系。
  2.中介的责任过于重大和复杂,很容易写错了。



22访问者模式

  对于关系稳定一个或几个对象有不同的操作,我们将对象和该操作分离,可以方便在增加新的操作的时候直接扩充。

分析

  1.优点:对于操作类(我们容易操作),我们很容易做到扩充。
  2.缺点:对于对象结构复杂,不稳地的,在增加一个对象的时候,在操作中会增加很多的方法。因此该方法比较适用于结构稳定的结构及相关算法。



结语


遗留问题

  1.适配器模式和解释器模式,他们之间的差别不是能够太理解。

  2.这些设计模式,自己看着可以理解,但是要说为什么是这样的,这样为啥比较好,对他们的设计初衷,我现在还是体会不到。

  3.对于模式中画的uml图,有些线的关系,自己不太清楚,可以在这方面有所加强。


碎碎念

 说实话自己码了这么多,最后也是有小小的成就感,这里不得不说的就是自己的时间管理吧,这段时间的毕业设计,自己的项目也延期了,这是自己要反思的地方了。最后想说的是,对于上面的模式的理解和uml图的画法肯定是不够完善的,希望多多指点~

 

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 29
    评论
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值