设计模式:考试总结
发布日期:2021-07-01 04:10:33 浏览次数:2 分类:技术文章

本文共 21545 字,大约阅读时间需要 71 分钟。

绪论

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

一个模式有四个基本要素:

  1. 模式名称(pattern name):一个助记名,它用一两个词来描述模式的问题、解决方案和效果。
  2. 问题(problem):描述了应该在何时使用模式。
    • 不是基本的数据结构,也不是整个系统。
    • 不特定于域。
  3. 解决方案(solution):描述了设计的组成成分,它们之间的相互关系及各自的职责和协作方式。
  4. 效果(consequences):描述了模式应用的效果及使用模式应权衡的问题。
    • 对时间和空间的衡量。
    • 语言和实现问题。
    • 对系统灵活性、扩充性或可移植性的影响。

设计模式扮演的角色:

  • 应用程序:减少类依赖性、平台依赖性。
  • 工具箱:代码复用。
  • 框架:强调设计重用,在框架中使用模式使学习框架的使用更加容易。

设计模式与框架最主要的不同在于如下三个方面:

  1. 设计模式比框架更抽象。
  2. 设计模式是比框架更小的体系结构元素。
  3. 框架比设计模式更加特例化。
  • 使用设计模式的缺点:
    • 使设计复杂化。
    • 根据空间和时间要求,降低系统性能。
  • 仅在需要时使用设计模式:
    • 灵活性。
    • 可扩展性。
    • 便携性。

实例研究:设计一个文档编辑器

设计问题:

  • 文档结构:组合模式
  • 格式化:策略模式
  • 修饰用户界面:装饰模式
  • 支持多种视感标准:抽象工厂模式
  • 支持多种窗口系统:桥接模式
  • 用户操作:命令模式
  • 拼写检查和断字处理:迭代器模式和访问者模式

文档结构:组合模式

在这里插入图片描述

在这里插入图片描述

class Glyph {
public: virtual void Draw(Window *) = 0; virtual void Bounds(Rect &) = 0; virtual bool Intersects(const Point &) = 0; virtual void Insert(Glyph *, int) = 0; virtual void Remove(Glyph *) = 0; virtual Glyph *Child(int) = 0; virtual Glyph *Parent() = 0;}

程序格式化示例

在这里插入图片描述

在这里插入图片描述

格式化:策略模式

在这里插入图片描述

void Composition::Compose() {
switch (_breakingStrategy) {
case SimpleStrategy: ComposeWithSimpleStrategy(); break; case TexStrategy: ComposeWithTexStrategy(); break; // ... }}// With strategy patternvoid Composition::Compose() {
_compositor->Compose(); // ...}

修饰用户界面:装饰模式

  • 使用类继承或mixin class的缺点
    • 运行时不能扩展或删除功能。
    • 如果有许多装饰功能,子类的数量就会激增。
  • 使用类组合的缺点
    • 两个类的接口不同。
    • 难以递归装饰。
    • 基本类必须注意接口元素。

在这里插入图片描述

装饰模式与复合模式的比较

  • 装饰模式是退化的复合模式。
  • 意图不同:
    • 装饰:用于添加其他功能。
    • 复合:用于对象聚合。

I/O 流示例

在这里插入图片描述

Stream *fStream = new FileStream("test.cpp");Stream *mStream = new MemoryStream();Stream *fcStream = new CompressingStream(        new FileStream("test.cpp"));Stream *f7Stream = new ASCII7Stream(new FileStream("test.cpp"));Stream *fc7Stream = new CompressingStream(        new ASCII7Stream(new FileStream("test.cpp")));fc7Stream->PutInt(12);fc7Stream->PutString("hello");

支持多种视感标准:抽象工厂模式

在这里插入图片描述

switch (Style)  {
case Motif: ScrollBar * sb = new MotifScrollBar; Button * bn = new MotifButton; Menu * mn = new MotifMenu; break;case Mac: ScrollBar * sb = new MacScrollBar; Button * bn = new MacButton; Menu * mn = new MacMenu; break;case PM: ScrollBar * sb = new PMScrollBar; Button * bn = new PMButton; Menu * mn = new PMMenu; break;}// With abstract factory patternswitch (Style) {
case Motif: guiFactory = new MotifFactory( ); break; case Mac: guiFactory = new MacFactory( ); break; case PM: guiFactory = new PMFactory( ); break;}ScrollBar * sb = guiFactory->CreateScrollBar( );Button * bn = guiFactory->CreateButton( );Menu * mn = guiFactory->CreateMenu( );// new ImplementationWidget * MotifFactory::Make(string name){
if ( name == "ScrollBar" ) return new MotifScrollBar(); // other widgets ... // to append a new widget if ( name == "ListBox" ) return new MotifListBox(); }//...ScrollBar * sb = dynamic_cast
(guiFactory->Make("ScrollBar") );ListBox * lb = dynamic_cast
(guiFactory->Make(“ListBox”);

支持多种窗口系统:桥接模式

在这里插入图片描述

桥接模式和策略模式之间的区别:

  • 策略模式:
    • 对于一个操作,可以运行时开关,具有上下文。
  • 桥接模式:
    • 类层次结构。

用户操作:命令模式

在这里插入图片描述

在这里插入图片描述

命令模式的应用

  • 支持撤消。
  • 支持上下文相关菜单。
  • 支持命令宏。
  • 支持记录更改以恢复崩溃的系统。
  • 支持信息系统中的事务概念。

拼写检查和断字处理:迭代器模式和访问者模式

迭代器模式

template
class List {
List(long size = DEFAULT_LIST_CAPACITY); long count() const; Item &Get(long index) const; void print();}template
class Iterator {
public: virtual void First() = 0; virtual void Nex() = 0; virtual bool IsDone() const = 0; virtual Item CurrentItem() const = 0;protected: Iterator();}template
class ListIterator : public Iterator
{
public: ListIterator(const List
*aList) : _list(aList), _current(0) {
}; virtual void First() {
_current = 0; } virtual void Next() {
_current++; } virtual bool IsDone() const {
return _current >= _list->Count(); } virtual Item CurrentItem() const {
if (IsDone()) throw IteratorOutOfBounds; return _list->Get(_current); }private: const List
*_list; long _current;}void PrintEmployees(ListIterator
&i) { for (i.First(); !i.IsDone(); i.Next()) { i.CurrentItem()->Print(); }}List
*employees;ListIterator
forward(employees);ReverseListIterator
backward(employees);PrintEmployees( forward );PrintEmployees( backward );

在这里插入图片描述

保证迭代器被删除:动态分配的迭代器对象在使用完毕后,必须删除这个迭代器,否则会造成内存泄露。IteratorPtr 提供作为一个迭代器的代理,通过定义私有的 new 和 delete 操作符来保证 IteratorPtr 总在栈上分配,可以保证在 Iterator 对象离开作用域时清除它。并且重载了“->”和“*”操作符为指向迭代器的指针,使得和调用迭代器的语法相同。

template
class IteratorPtr {
public: IteratorPtr(Iterator
*i) : _i(i) {
} ~IteratorPtr() {
delete _i; } Iterator
*operator->() {
return _i; } Iterator
&operator*() {
return *_i; }private: // to avoid multiple deletions of _i IteratorPtr(const IteratorPtr &); IteratorPtr &operator=(const IteratorPtr &);private: Iterator
*_i;}// pseudo-codevoid ConditionalInsert(AbstractList *list, Item I) {
IteratorPtr it(list->CreateIterator()); // syntax of using an IteratorPtr object is as the // same as the Iterator* for (it->First(); !it->IsDone; it->Next()) if (it->CurrentItem == I) break; if (!it->IsDone) return; // the item already exist. list->Append(I); // the "Iterator*" will be deleted automatically}

迭代器模式:先序遍历

void PreorderIterator::Next() {
Iterator < Glyph * > *i = _iterators.Top()->CurrentItem()->CreateIterator(); i->First(); _iterators.Push(i); while (_iterators.Size() > 0 && _iterators.Top()->IsDone()) {
delete _iterators.Pop(); _iterators.Top()->Next(); }}

访问者模式

void SpellingChecker::Check( Glyph * glyph ) {
Character * c; Row * r; Image * i; if (c=dynamic_cast
(glyph)) {
// analyze the character }else if (r=dynamic_cast
(glyph ) {
// prepare to analyze r's children }else if (i=dynamic_cast
(glyph ) {
// do nothing }}SpellingChecker spellingChecker;Composition *c;Glyph * g;PreorderIterator i(c);for ( i.First(); ! i.IsDone(); i.Next() ) {
g = i.CurrentItem( ); SpellingChecker.Check( g );}// With visitor patternvoid Subclass::CheckMe(SpellingChecker& checker) {
checker.Check(this);}class SpellingChecker {
public: SpellingChecker(); void Check(Character*); void Check(Row*); void Check(Image*);private: char _currentWord[ MAX_WORD_SIZE ]; }SpellingChecker spellingChecker;Composition *c;Glyph * g;PreorderIterator i(c);for ( i.First(); ! i.IsDone(); i.Next() ) {
g = i.CurrentItem( ); g.CheckMe( spellingChecker );}

在这里插入图片描述


创建型模式

生成器模式

在这里插入图片描述

在这里插入图片描述

生成器隐藏了产品的内部结构和组装细节。

在这里插入图片描述

生成器模式和抽象工厂模式的区别

  • 生成器模式:
    • builder类负责组装产品,可能通过调用其他类来实现。
    • builder类逐步制造和组装产品。
  • 抽象工厂模式:
    • 抽象工厂模式的客户负责组装产品。
    • 工厂一次生产所有零件。

工厂方法模式

在这里插入图片描述

图表元素操作示例

在这里插入图片描述

层次结构部分平行。

实现代码

// Parameterized factory methodclass Creator {
virtual Product * Create(ProductID id) {
if (id==MINE) return new MyProduct; if (id==YOURS) return new YourProduct; ... }};class MyCreator: public Creator {
virtual Product * Create(ProductID id) {
if (id==YOURS) return new MyProduct; if (id==MINE) return new YourProduct; if (id==THEIRS) return new TheirProduct; ... return Creator::Create(id); }}// Template could be used to avoid sub-classing of the creator classclass Creator {
public: virtual Product * CreateProduct() = 0;};template
class StandardCreator: public Creator{
public: virtual Product* CreateProduct() {
return new TheProduct; }}StandardCreator
aCreator;StandardCreator
bCreator;

原型模式

在这里插入图片描述

实现代码

class CPrototypeMonster {
protected: CString _name;public: CPrototypeMonster(); CPrototypeMonster(const CPrototypeMonster ©); ~CPrototypeMonster(); virtual CPrototypeMonster *Clone() const = 0; void Name(CString name); CString Name() const;};class CGreenWigglyMonster : public CPrototypeMonster {
protected: int _numberOfArms; double _slimeAvailable;public: CGreenWigglyMonster(); CGreenWigglyMonster(const CGreenWigglyMonster ©); ~CGreenWigglyMonster(); virtual CPrototypeMonster *Clone() const; void NumberOfArms(int numberOfArms); void SlimeAvailable(double slimeAvailable); int NumberOfArms() const; double SlimeAvailable() const;};class CPurpleLongNoseMonster : public CPrototypeMonster {
protected: int _intensityOfBadBreath; double _lengthOfWhiplikeAntenna;public: CPurpleLongNoseMonster(); CPurpleLongNoseMonster(const CPurpleLongNoseMonster ©); ~CPurpleLongNoseMonster(); virtual CPrototypeMonster *Clone() const; void IntensityOfBadBreath(int intensityOfBadBreath); void LengthOfWhiplikeAntenna(double lengthOfWhiplikeAntenna); int IntensityOfBadBreath() const; double LengthOfWhiplikeAntenna() const;};class CGreenPotBellyMonster : public CPrototypeMonster {
protected: double _roomAvailableInBelly;public: CGreenPotBellyMonster(); CGreenPotBellyMonster(const CGreenPotBellyMonster ©); ~CGreenPotBellyMonster(); virtual CPrototypeMonster *Clone() const; void RoomAvailableInBelly(double roomAvailableInBelly); double RoomAvailableInBelly() const;};CPrototypeMonster::CPrototypeMonster(const CGreenWigglyMonster ©) {
_name = copy._name;}CGreenWigglyMonster::CGreenWigglyMonster(const CGreenWigglyMonster ©) : CPrototypeMonster(copy) {
_numberOfArms = copy._numberOfArms; _slimeAvailable = copy.slimeAvailable;}CPurpleLongNoseMonster::CPurpleLongNoseMonster(const CPurpleLongNoseMonster ©) : CPrototypeMonster(copy) {
_intensityOfBadBreath = copy._intensityOfBadBreath; _lengthOfWhiplikeAntenna = copy._lengthOfWhiplikeAntenna;}CGreenPotBellyMonster::CGreenPotBellyMonster(const CGreenPotBellyMonster ©) : CPrototypeMonster(copy) {
_roomAvailableInBelly = copy._roomAvailableInBelly;}CPrototypeMonster *CGreenWigglyMonster::Clone() const {
return new CGreenWigglyMonster(*this);}CPrototypeMonster *CPurpleLongNoseMonster::Clone() const {
return new CPurpleLongNoseMonster(*this);}CPrototypeMonster *CGreenPotBellyMonster::Clone() const {
return new CGreenPotBellyMonster(*this);}void DoCoolStuffWithAMonster(const CPrototypeMonster *originalMonster) {
CPrototypeMonster *newMonster = originalMonster->Clone(); ASSERT(newMonster); newMonster->Name("A name"); // Add code doing all sorts of cool stuff with the monster. delete newMonster;}

使用原型管理器

class CBasePrototype {
protected: CString _name;public: CBasePrototype(); CBasePrototype(const CBasePrototype ©); ~CBasePrototype(); virtual CBasePrototype *Clone(CString _name) const = 0; void Name(CString name); CString Name() const;};class CPrototypeManager {
protected: std::list
_prototypeList;public: CPrototypeManager(); CPrototypeManager(const CPrototypeManager ©); ~CPrototypeManager(); unsigned intNumberOfPrototypes() const; void AddPrototype(CBasePrototype *prototype); void DeletePrototype(const CString *label); void DeleteAllPrototypes(); CBasePrototype *FindPrototype(const CString *label); const CBasePrototype *FindPrototype(const CString *label); std::list
AvailablePrototypes() const;};

结构型模式

适配器模式

在这里插入图片描述

class Shape {
public: Shape(); virtual void BoundingBox(Point &bottomLeft, Point &topRight) const; virtual Manipulator *CreateManipulator() const;};class TextView {
public: TextView(); void GetOrigin(Coord &x, Coord &y) const; void GetExtent(Corrd &width, Coord &height) const; virtual bool IsEmpty() const;}class TextShape : public Shape, private TextView {
public: TextShape(); virtual void BoundingBox(Point &bottomLeft, Point &topRight) const {
Corrd bottom, left, width, height; GetOrigin(bottom, left); GetExtent(width, height); bottomLeft = Point(bottom, left); topRight = Point(bottom + height, left + width); } virtual bool IsEmpty() const {
return TextView::IsEmpty(); } virtual Manipulator *CreateManipulator() const {
return new TextManipulator(this); }};

Lambda 示例

#include 
#include
//Adaptee 1struct CoffeMaker {
void Brew(double quantity, double temp) const {
std::cout << "I am brewing " << quantity << "ml coffee @" << temp << " degree C" << std::endl; }};//Adaptee 2 (having difference interface from Adaptee 2)struct JuiceMaker {
void Squeeze(double quantity) const {
std::cout << "I am making " << quantity << "ml Juice" << std::endl; }};// Targetstruct Beverage {
virtual void getBeverage(int quantity) = 0;};// Adapterclass Adapter : public Beverage {
std::function
Request;public: Adapter(CoffeMaker *cm1) {
Request = [cm1](int quantity) {
cm1->Brew(quantity, 80); }; } Adapter(JuiceMaker *jm1) {
Request = [jm1](int quantity) {
jm1->Squeeze(quantity); }; } void getBeverage(int quantity) {
Request(quantity); }};//Clientint main() {
CoffeMaker coffeMaker; Adapter adp1(&coffeMaker()); adp1.getBeverage(30); JuiceMaker juiceMaker Adapter adp2(&juiceMaker); adp2.getBeverage(40);}

外观模式

在这里插入图片描述

行为模式

职责链模式

在这里插入图片描述

void Handler::handleRequest(Request *theRequest) {
switch (theRequest->getKind()) {
case Help: // cast argument to appropriate type handleHelp((HelpRequest *) theRequest); break; case Keyboard_Message: handlePrint((Keyboard_Message *) theRequest); break; default: // ... break; }}typedef int Topic;const Topic NO_HELP_TOPIC = -1class HelpHandler {
public: HelpHandler(HelpHandler *successor = 0, Topic= NO_HELP_TOPIC); virtual bool hasHelp(); virtual void setHandler(HelpHandler *successor, Topic); virtual void handleHelp();private: HelpHandler *_successor; Topic _topic;};HelpHandler::HelpHandler(HelpHandler *successor, Topict) : _successor(successor), _topic(t) {
}bool HelpHandler::hasHelp() {
return _topic != NO_HELP_TOPIC;}void HelpHandler::handleHelp() {
if (_successor != 0) {
_successor->handleHelp(); }}class Widget : public HelpHandler {
protected: Widget(Widget *parent_, Topic t = NO_HELP_TOPIC);private: Widget *parent;}Widget::Widget(Widget *parent_, Topic t) :HelpHandler(parent_, t) {
parent = parent_;}class Button : public Widget {
public: Button(Widget *parent_, Topic t = NO_HELP_TOPIC); virtual void handleHelp();}Button::Button(Widget *parent_, Topic t) :Widget(parent_, t) {
}void Button::handleHelp() {
if (hasHelp()) {
// Offer help on the button } else {
HelpHandler::handleHelp(); }}class Dialog : public Widget {
public: Dialog(HelpHandler *parent_, Topic t = NO_HELP_TOPIC); virtual void handleHelp();}Dialog::Dialog(HelpHandler *parent_, Topic t) :Widget(0) {
setHandler(parent_, t);}void Dialog::handleHelp() {
if (hasHelp()) {
// offer help on the dialog } else {
HelpHandler::HandleHelp(); }}class Application : public HelpHandler {
public: Application(Topic t) : HelpHandler(0, t) {
} virtual void handleHelp();}void Application::handleHelp() {
// application-specific operations, eg. // show a list of help topics}const Topic APPLICATION_TOPIC = 1;const Topic PRINT_TOPIC = 2;const Topic PAPER_ORIENTATION_TOPIC = 3;Application *application = new Application(APPLICATION_TOPIC);Dialog *dialog = new Dialog(application, PRINT_TOPIC);Button *button = new Button(dialog, PAPER_ORIENTATION_TOPIC);

解释器模式

在这里插入图片描述

class BooleanExp {
public: BooleanExp(); virtual ~BooleanExp(); virtual bool Evaluate(Context &) = 0; virtual BooleanExp *Replace(const char *, BooleanExp &) = 0; virtual BooleanExp *Copy() const = 0;}class Context {
public: bool Lookup(const char *) const; void Assign(VariableExp *, bool);}class VariableExp : public BooleanExp {
public: VariableExp(const char *name) {
_name = strdup(name); } virtual ~VariableExp(); virtual bool Evaluate(Context &aContext) {
return aContext.Lookup(_name); } virtual BooleanExp *Replace(const char *name, BooleanExp &exp) {
if (strcmp(name, _name) == 0) return exp.Copy(); else return new VariableExp(_name); } virtual BooleanExp *Copy() const {
return new VariableExp(_name); }private: char *_name;}class AndExp : public BooleanExp {
public: AndExp(BooleanExp *op1, Boolean *op2) {
_operand1 = op1; _operand2 = op2; } virtual ~AndExp(); virtual bool Evaluate(Context &aContext) {
return _operand1->Evaluate(aContext) && _operand2->Evaluate(aContext); } virtual BooleanExp *Replace(const char *name, BooleanExp &exp) {
return new AndExp( _operand1->Replace(name, exp), _operand2->Replace(name, exp)) } virtual BooleanExp *Copy() const {
return new AndExp( _operand1->Copy(), _operand2->Copy()) }}void main() {
// The expression is: (true and x ) or (y and (not x) ) BooleanExp *expression; Context context; VariableExp *x = new VariableExp("X"); VariableExp *y = new VariableExp("Y"); Expression = new OrExp( new AndExp(new Constant(true), x), new AndExp(y, new NotExp(x)) ); context.Assign(x, false); context.Assign(y, true); Bool result = expression->Evaluate(context); // Now we replace the variable y with a new expression and // re-evaluate the expression VariableExp *z = new VariableExp("Z"); NotExp not_z(z); BooleanExp *replacement = expression->Replace("Y", not_z); context.Assign(z, true); result = replacement->Evaluate(context);}

观察者模式

在这里插入图片描述

Sort 案例

概述

对一个文件的所有行进行排序。

支持的运行参数

-i : 忽略大小写
-n: 将关键字看作数字,按照数字大小进行排序
-f k: 关键字从第k个field开始。默认情况为整个一行
-c k:关键字从第k列开始。默认情况为整个一行
-p [ first | random | median3 ]:指定 pivot 值
-r : 降序输出,默认情况为升序输出

在这里插入图片描述

  • Singleton
    • Options, System_Sort, Compare_Func_Factory
  • Strategies
    • Pivot_Strategies以及其三个子类
  • Adaptor
    • Sort_AT_Adaptor
  • Facade
    • System_Sort
class Options {
public: enum Pivot_Strategy {
FIRST, RANDOM, MEDIAN3 }; static Options *instance(); void parse_args(int argc, char **argv); bool ignore_case(); bool key_is_numeric(); bool reverse_output(); int field_offset(); int column_offset(); Pivot_Strategy pivot_strat(); char *file_name();private: Options(); bool _ignore_case; bool _key_is_numeric; bool _reverse_output; int _field_offset, _column_offset; Pivot_Strategy _pivot_strat; char *_file_name; static Options _instance;};class Input {
public: Input(); char *read(char *file_name); char *buffer() const; size_t num_lines() const;private: size_t _num_lines; char *_buffer;};template
class Array {
public: void Resize(size_t size = 0) {
_size = size; _array = new T[_size]; } ~Array() {
delete[] _array; }; T &operator[](size_t index) {
return _array[index]; } size_t size() const {
return _size; }private: T *_array; size_t _size;};template
class Access_Table {
public: virtual int make_table(char *buffer, size_t num_lines) = 0; T &element(size_t index) {
return _access_array[index]; }; size_t length() const {
return _access_array.size(); } virtual ~Access_Table() {
delete _access_buffer; };protected: Array
_access_array; char *_access_buffer;};class Pivot_Strategies {
public: virtual int get_pivot(Sort_AT_Adaptor &, int lo, int hi) = 0;};class First_Pivot : public Pivot_Strategies {
public: virtual int get_pivot(Sort_AT_Adaptor &, int lo, int hi);};class Random_Pivot : public Pivot_Strategies {
public: Random_Pivot(); virtual int get_pivot(Sort_AT_Adaptor &, int lo, int hi);};class Median3_Pivot : public Pivot_Strategies {
public: virtual int get_pivot(Sort_AT_Adaptor &, int lo, int hi);};class Line_Ptrs {
public: // Comparison operator used by sort(). int operator<(const Line_Ptrs &) const; // Beginning of line and key (field or column). char *_bol, *_bok;};int Line_Ptrs::operator<(const Line_Ptrs &p) const {
Compare_Func_Factory::Func_Pointer fp; fp = Compare_Func_Factory::instance()->get_func_pointer(); return ((*fp)(this->_bok, r._bok) <= 0);}class Sort_AT_Adaptor : private Access_Table
{
public: virtual int make_table(char *buffer, size_t num_lines); Line_Ptrs &operator[](size_t index) {
return element(index); } size_t size() const {
return length(); } friend std::ostream &operator<<(std::ostream &os, Sort_AT_Adaptor &sort_at_adaptor);};class Compare_Func_Factory {
public: typedef int (*Func_Pointer)(const char *, const char *); static Compare_Func_Factory *instance(); void set_func_pointer(); Func_Pointer get_func_pointer();private: Compare_Func_Factory(); static Compare_Func_Factory _instance; Func_Pointer _func_pointer;};

转载地址:https://mortal.blog.csdn.net/article/details/92421481 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:设计模式:考试总结(背版)
下一篇:机器学习:总结(周某华)

发表评论

最新留言

表示我来过!
[***.240.166.169]2024年04月10日 12时14分55秒