常用设计模式

1、设计模式简介

什么是模式?

有一些问题及其解决方案不断变换面孔重复出现,在这些不同的面孔后面是共同的本质;这些共同的本质就是模式。

设计模式是特定开发场景下针对特定问题的一种解决方案。

  创建型模式解决的问题就是如何创建对象,何时创建对象,它努力的让代码不要太多的关注对象的具体类型,不用关注对象的创建细节,而只须要了解对象的抽象类型,创建对象的工作由创建对象的工厂来实现。

  面向对象的系统中,对象如何组织,采用什么样的结构组织比较合理,这个是由结构型模式来处理的。合理的使用结构型模式可以使系统具备更好的灵活性、扩展性和维护性。
  行为模式规定了各个对象间的应该具备的职责。

 设计模式不是重用代码,而是重用经验。

 

2、常用的几种设计模式

(1)简单工厂模式

 

  严格来说,简单工厂模式并不是 23 种标准模式之一,它是工厂家族中最简单的模式,使用这个模式可以把对象的创建和对象的使用分离分开,工厂只负责对象的创建,客户端程序调用和使用对象,客户端程序无需创建对象。对象的创建放在一起,方便维护和扩展。

 

   如上图所示:右上角是一个产品接口,可以使用接口或抽象类来定义一个产品对象,Animal 类中有一个行为 eat(),Animal 类派生出两个子类 Dog、Penguin,这两个类分别实现了 eat()方法,这两个动物其实是简单工厂中具体的产品,通过它们实现抽象的产品。

  这些动物如何去创建呢?可以用动物工厂 AnimalFactory 来创建具体的动物,AnimalFactory 类中有一个 GetAnimal 方法,在这个方法里可以根据传进去的参数来创建具体的产品,工厂类和产品类是依赖的关系。
  在客户端,关联了抽象的产品类 Animal 和工厂类 AnimalFactory。对客户来说,不须要了解具体的产品,只要须要告诉工厂,需要什么具体的动物,动物工厂就会根据客户端的要求来创建某个动物,通过简单工厂模式,使客户端程序与具体的产品之间减少耦合度。

 

(2)工厂方法模式

  这是用得比较多的一种设计模式,也是 23 标准设计模式之一。使用前面讲的简单工厂设计模式,遇到具体产品经常变化时就不太适合了,违反了开闭设计原则。怎么才能避免修改工厂类呢?工厂方法模式可以做得到!
  工厂方法模式要求应该有一个抽象的工厂类,然后在抽象工厂类中定义一个生成产品的方法,这个方法就是工厂方法,这也是工厂方法模式的由来。该方法具体的行为会由它的子类或实现类来实现。
  如果想生产某种产品,就定义一个新的产品和新的产品工厂类,这样就实现了不同的产品进行不同的创建,原来写好的代码不会发生变化。这种方式符合开闭原则,可扩展比较好。

 

 

 

(3)单例模式

  单例设计模式也是创建型模式的一种,也是 23 种设计模式中比较简单的一种。在整个软件系统中,只有某个类型的一个对象,并且访问它的地方也只有一个,即只有一个全局对象访问点,这个实例或对象被所有的应用程序所共享。
  很多可以使用到这样的功能模块,比如数据库连接池对象、打印机对象。整个系统中,数据库的连接可能只在一个地方连接,打印机在整个系统中也只有一个。采用这种模式就很大的减少了内存的开销,因为对象的创建是比较消耗内存的,同时因为系统中只有一个实例,比较容易控制,省去了对象创建的过程,可以更快的进行响应。
  单例模式只需要一个类就可以实现,自己关联自己,那是如何实现呢?只需要将构造方法定义成私有的,这样用户就不能自己去创建这个对象了,然后通过一个静态方法和静态变量来存放类的唯一的一个实例!
 
(4)策略模式
  所谓策略其实就是做一件事情有很多很多的方法。比如一个商场要搞促销,促销的方式有可能有很多:打折、满 50 返 100、积分等等之类的。这种不同的促销方式在系统中表示就是一个一个的策略,并且策略是可以随时更换的,在设计系统时就可以使用策略模式。
  商场有可能会更换或追加新的促销模式,也就是策略存在调整,会更改以前的代码,为了满足开闭原则,这时就要使用抽象类和接口。这里偏向使用接口,在接口里定义策略的方法,根据不同的情况编写不同的实现类,实现不同的策略。因此,策略模式比较适用于算法经常变化的情况,比如计算工资的方式、出行方式的选择等等。
 
  
  如上图所示,在商场促销例子中,先定义策略的接口(Promotion),然后在这个策略接口里定义策略的方法(getPrice()),接着定义了两种具体的策略(Discount 打折)和(MoneyBack 返现).
  策略模式会专门有一个上下文对象(PromotionContext)专门管理策略类,并且上下文对象和策略接口之间是聚合的关系,也就是整体和部分的关系,因此在上下文对象里应该保存一个对促销类型的引用。另外上下文对象里一般会有一些方便客户端调用的方法如 getPrice(),客户端程序可以通过上下文对象得到价格,这个 getPrice 里会根据不同的策略,执行不同的策略方法。
  如果客户端不想使用上下文中定义的默认的策略,也可以去修改策略类,因此上下文中有一个 changePromotion()方法。客户端主要使用上下文对象,如果需要修改策略,还要依赖于具体的策略对象。
posted @ 2023-03-28 14:04  Linqylin  阅读(21)  评论(0编辑  收藏  举报