Skip to content

Latest commit

 

History

History
142 lines (85 loc) · 7.76 KB

File metadata and controls

142 lines (85 loc) · 7.76 KB

问题与简答

设计模式篇

什么是设计模式

每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样,你就能一次又一次地使用该方案而不必做重复劳动

模式要素:模式名称、问题、解决方案、效果

如何理解框架

框架是构成一类特定软件可复用设计的一组相互协作的类。框架规定了应用的体系结构。定义了整体结构,类和对象的分隔,各部分的主要责任,类和对象怎么协作,以及控制流程。框架预定义了这些设计参数,以便于应用设计者或实现者能集中精力于应用本身的特定细节。框架记录了其应用领域的共同的设计决策。因而框架更强调设计复用,尽管框架常包括具体的立即可用的子类

主要设计模式

创建型

  • 单例(Singleton):保证一个类仅有一个实例,并提供一个访问它的全局访问点
  • 抽象工厂(Abstract Factory):提供一个创建一系列相关或相互依赖对象的接口
  • 工厂方法(Factory Method):定义一个用于创建对象的接口,让子类决定哪一个类实例化
  • 原型(Prototype):用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象

结构型

  • 适配器(Adapter):将一个类的接口转换成期望的另一个接口
  • 代理(Proxy):为其他对象提供一个代理以控制对这个对象的访问

行为型

  • 备忘录(Memento):备忘录对象是一个用来存储另外一个对象内部状态的快照的对象。备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态捉住,并外部化,存储起来,从而可以在将来合适的时候把这个对象还原到存储起来的状态
  • 观察者(Observer):在对象间定义一个一对多的联系性,由此当一个对象改变了状态,所有其他相关的对象会被通知并且自动刷新
  • 策略(Strategy):定义一个算法的系列,将其各个分装,并且使他们有交互性。策略模式使得算法在用户使用的时候能独立的改变

怎样选择设计模式

考虑设计模式是怎样设计问题的、浏览模式的意图部分、研究模式怎样互相关联、研究目的相似的模式、检查重新设计的原因、考虑你的设计中哪些是可变的

单例模式

保证一个类仅有一个实例,并提供一个访问它的全局访问点。让类自身负责保存它的唯一实例,并提供一个访问该实例的方法。这就是单例模式

适用性

  • 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时
  • 当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时

优点

  • 对唯一实例的受控访问
  • 避免全局变量污染
  • 允许对操作和表示精化
  • 允许可变数目的实例
  • 比类操作更灵活

抽象工厂模式

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类

“工厂”是创建产品(对象)的地方,其目的是将产品的创建与产品的使用分离。抽象工厂模式的目的,是将若干抽象产品的接口与不同主题产品的具体实现分离开。这样就能在增加新的具体工厂的时候,不用修改引用抽象工厂的客户端代码

适用性

  • 一个系统要独立于它的产品的创建、组合和表示时
  • 一个系统要由多个产品系列中的一个来配置时
  • 需要强调一系列相关的产品对象的设计以便进行联合使用时
  • 提供一个产品类库,而只想显示它们的接口而不是实现时

优点

  • 具体产品从客户代码中被分离出来
  • 容易改变产品的系列
  • 将一个系列的产品族统一到一起创建

缺点

  • 在产品族中扩展新的产品是很困难的,它需要修改抽象工厂的接口

工厂方法模式

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

适用性

  • 当一个类不知道它所必须创建的对象的类的时候
  • 当一个类希望由它的子类来指定它所创建的对象的时候
  • 当类将创建对象的职责委托给多个帮忙子类的中的某一个,并且你希望将哪一个帮助子类是代理者者一信息局部化的时候

适配器模式

将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作

适用性

  • 你想使用一个已经存在的类,而它的接口不符合你的需求
  • 你想创建一个可以复用的类,改类可以与其他不相关的类或不可预见(可能不兼容)的类协同工作
  • 你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口

观察者模式

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新

适用性

  • 当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用
  • 当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变
  • 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之,你不知道这些对象时紧密耦合的

策略模式

定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化

适用性

  • 许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法
  • 需要使用一个算法的不同变体
  • 算法使用客户不应该知道的数据。避免暴露复杂的、与算法相关的数据结构
  • 一个类定义了多种行为,并且这些行为在类的操作中以多个条件语句的形式出现

OOP 思想

面向对象程序设计(Object-oriented programming,OOP)是种具有对象概念的程序编程典范,同时也是一种程序开发的抽象方针

抽象类和接口

抽象类可以为项目提供一种组织机制。抽象类不能实例化,只能由具体(可实例化的类)继承抽象类的接口以及它的所有具体属性

与大多数抽象类一样,接口也有抽象方法。不过,不能像在抽象类中那样在接口中包含具体方法或变量

控制反转

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中

依赖注入

依赖注入是将所依赖的传递给将使用的从属对象(即客户端)。该服务是将会变成客户端的状态的一部分。 传递服务给客户端,而非允许客户端来建立或寻找服务

实现方式

  • 基于接口。实现特定接口以供外部容器注入所依赖类型的对象
  • 基于 set 方法。实现特定属性的 public set 方法,来让外部容器调用传入所依赖类型的对象
  • 基于构造函数。实现特定参数的构造函数,在新建对象时传入所依赖类型的对象