《面向对象设计模式》一书

图片您好,habrozhiteli!自“设计模式”首次印刷运行以来已经过去了25多年。在这段时间里,这本来自大众的书变成了邪教。在世界各地,建议将其阅读给任何想将生活与信息技术和编程联系起来的人。 IT人员使用的“俄语”语言已发生变化,许多英语术语已变得熟悉,模式已进入我们的生活。

这是一本周年纪念版,其中包含本书的最新翻译版本,这已成为每个程序员必读的内容。 “面向对象设计模式”取代了“面向对象设计技术”。

四个一流的开发人员(四人一组)以二十三个模式的形式提请您注意OOP的经验。之所以出现模式,是因为开发人员正在寻找增加其程序的灵活性和重用程度的方法。作者不仅提供了使用设计模式的原则,而且还系统化了信息。您将了解模式在复杂系统的体系结构中的作用,并且能够在开发大型项目时考虑到所有限制,从而快速有效地创建自己的应用程序。所有模板均取自真实系统,并基于真实实践。每个模式均显示C ++或Smalltalk代码,以证明其功能。

前言


本书描述了针对面向对象设计中出现的典型问题的简单而优雅的解决方案。

之所以出现模式,是因为许多开发人员正在寻找增加程序灵活性和重用程度的方法。所找到的解决方案以简洁且易于实践的形式体现。四人帮以简单易懂的示例以清晰易懂的语言解释每种模式。在软件系统开发中使用模式使设计人员可以进行更高级别的项目开发。现在,架构师和程序员可以使用图形名称来进行操作,并以一种语言进行交流。

因此,这本书解决了两个问题。

首先,它介绍了模式在创建复杂系统的体系结构中的作用。

其次,它允许设计人员使用手册中包含的模式轻松开发自己的应用程序。

2020年版发生了什么变化?

  • 术语已更新(例如,“重构”一词已为代码的“重组”扎根,因为共享是“共享”而不是“分离”,而mixin是“混合物”);
  • 更新风格;
  • 消除了不必要的笨重单词(例如,“规范”或“实例化”。第一个可以完全用“定义”代替,第二个可以用“创建实例”)。
  • 这本书最终被称为“面向对象的设计模式”。

模式模板法(模板法)


模式的名称和分类

模板方法是类行为的模式。

目的

模板方法定义了算法的基础,并允许子类重新定义算法的某些步骤,而无需整体上更改其结构。

动机

考虑具有Application和Document类的应用程序框架。 Application类负责打开以外部格式(例如,文件格式)存储的现有文档。从文件中读取文档信息后,Document类的对象代表文档信息。

基于此框架构建的应用程序可以产生满足特定需求的Application和Document类的子类。

例如,图形编辑器定义DrawApplication和DrawDocument的子类,而电子表格定义SpreadsheetApplication和SpreadsheetDocument的子类。

图片

抽象类Application定义了一种用于在OpenDocument操作中打开和读取文档的算法:

void Application::OpenDocument (const char* name) {
      if (!CanOpenDocument(name)) {
          //   
          return;
      }

      Document* doc = DoCreateDocument();

      if (doc) {
          _docs->AddDocument(doc);
          AboutToOpenDocument(doc);
          doc->Open();
          doc->DoRead();
      }
}

OpenDocument操作定义了打开文档的所有步骤。它检查是否可以打开文档,创建Document类的对象,将其添加到文档集中并从文件中读取文档。

形式为OpenDocument的操作将称为模板方法,该方法在子类中替换为获得所需行为的抽象操作类别中描述算法。 Application类的子类验证它们可以打开(CanOpenDocument)并创建文档(DoCreateDocument)。 Document类的子类读取文档(DoRead)。模板方法还定义了一个操作,该操作允许Application子类获取有关文档即将打开的信息(AboutToOpenDocument)。

模板方法使用抽象操作定义了算法的某些步骤,捕获了它们的序列,但允许将它们实现在Application和Document类的子类中。

适用性

应用模式模板方法的基本条件:

  • 单一使用算法的不变部分,而变化行为的实现仍由子类决定;
  • 为了避免代码重复,需要将所有子类共有的行为隔离和定位在一个类中。这是William Opdyke和Ralph Johnson [OJ93]描述的“用括号包围概括”技术的一个很好的例子。首先,揭示现有代码中的差异,然后将其转移到单独的操作中。最终,将不同的代码片段替换为模板方法,从该模板方法中调用新操作。
  • 子类扩展管理。可以定义模板方法,以便在特定点触发钩子(请参见结果部分),从而仅允许在这些点进行扩展。

结构体

图片

参与者

AbstractClass(Application)-抽象类:

  • 定义在特定子类中替换的抽象原始操作,以实现算法的步骤;
  • 实现了定义算法框架的模板方法。模板方法调用原始操作,以及在AbstractClass类或其他对象中定义的操作。

ConcreteClass(MyApplication)-特定类:

  • 实现原始操作,这些操作以依赖于子类的方式执行算法的步骤。



ConcreteClass 关系假定算法的不变步骤将在AbstractClass中执行。

结果

模板方法是重用代码的基本技术之一。它们在类库中扮演着特别重要的角色,因为它们提供了在库类中展现常见行为的能力。

模板方法导致倒置的代码结构,有时也被称为好莱坞原则,这意味着在这个电影帝国中经常使用的短语“不要打电话给我们,我们会打电话给您” [Swe85]。在这种情况下,这意味着父类将调用子类操作,反之亦然。

模板方法调用以下类型的操作:

  • 特定的操作(来自ConcreteClass类或来自客户端类);
  • AbstractClass类中的特定操作(即对所有子类有用的操作);
  • 基本操作(即抽象操作);
  • 工厂方法(请参阅工厂方法模式(135));
  • 钩子操作实现了可以在子类中扩展的默认行为。通常,这样的默认操作什么都不做。

模板操作必须清楚区分挂钩操作(可以替换)和抽象操作(必须替换),这一点很重要。为了最大程度地重用抽象类,子类作者需要了解打算替换哪些操作。

子类可以通过替换操作并从父类显式调用操作来扩展操作的行为:

void DerivedClass::Operation () {
      //   DerivedClass
      ParentClass::Operation();
}

不幸的是,很容易忘记需要调用继承的操作。可以将此类操作转换为样板方法,以提供对子类如何扩展它的父级控制。这个想法是从父类中的模板方法调用钩子操作。然后,子类将能够完全重新定义此操作:

void ParentClass::Operation () {
      //  ParentClass
      HookOperation();
}

在父类ParentClass中,HookOperation操作不执行任何操作:

void ParentClass::HookOperation () { }

子类重写HookOperation以扩展其行为:

void DerivedClass::HookOperation () {
   //    
}

实现

在实现模式模板方法时,应注意以下方面:

  • C++. , , . , . , , . , -;
  • . , . , ;
  • 命名约定。您可以通过在其名称上添加前缀来突出显示需要替换的操作。例如,在用于Macintosh应用程序的MacApp框架[App89]中,模板方法名称以Do前缀开头:DoCreateDocument,DoRead等。

代码示例

下面的C ++示例演示父类如何在其子类上施加不变式。一个例子来自NeXT AppKit库[Add94]。考虑一下View类,它支持在屏幕上绘图,这是一种不变的方法,其特征在于子类只有在焦点对准时才能更改视图。这要求设置特定的绘图上下文(例如,颜色和字体)。

您可以使用模板的Display方法设置状态。View类定义两个特定的操作(SetFocus和ResetFocus),它们分别设置和重置图形上下文。View类的View钩子操作会自己绘制图形。Display在DoDisplay之前调用SetFocus来准备上下文,在DoDisplay之后调用ResetFocus来重置上下文:

void View::Display () {
      SetFocus();
      DoDisplay();
      ResetFocus();
}

为了支持不变式,View类客户端始终调用Display,而View子类始终替换DoDisplay。

在View类中,DoDisplay操作不执行任何操作:

void View::DoDisplay () { }

子类重写它以添加其特定的绘图行为:

void MyView::DoDisplay () {
      //   
}

已知的应用程序

模板方法是如此基础,以至于几乎每个抽象类都可以找到它们。 Rebecca Wirfs-Brock等人[WBWW90,WBJ90]详细讨论了模板方法。

相关模式

工厂方法(135)通常从样板方法中调用。在“动机”部分的示例中,OpenDocument模板方法称为工厂DoCreateDocument方法。
策略(362):模板方法使用继承来修改算法的一部分。策略使用委派来整体修改算法。

»书上的更多信息上可以找到出版商的网站
» 目录
» 摘录

对于Khabrozhiteley 25%的优惠券- OOP

支付纸质版本的书后,就会通过电子邮件发送电子书。

All Articles