哈尔滨理工大学计算机学院
实验教学中心
《设计模式》实验
实验指导书... 3
实验一 Factory模式与Abstract Factory模式... 3
实验二 Adapter模式... 9
实验三 Observer模式... 12
实验四 Interpreter模式... 16
实验指导书
实验一 Factory模式与Abstract Factory模式
[实验目的]
1.掌握Factory模式与Abstract Factory模式的意图及其代码实现。
2.了解两种模式的区别。
[实验内容]
用C++语言实现Factory模式与Abstract Factory模式。
[实验要点及说明]
1、Factory模式
Factory模式的作用:
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。
UML 结构图:
抽象基类:
1)Product:创建出来的对象的抽象基类。
2)Factory:创建对象的工厂方法的抽象基类。
接口函数:
1)Creator::FactoryMethod:纯虚函数,由派生类实现,创建出对应的Product。
解析:
在这个模式中,有两个抽象基类,一个是Product为创建出来的对象的抽象基类,一个是Factory是工厂的抽象基类,在互相协作的时候都是由相应的Factory派生类来生成Product的派生类,也就是说如果要新增一种Product那么也要对应的新增一个Factory,创建的过程委托给了这个Factory,也就是说一个Factory和一个Product是一一对应的关系。
备注:
设计模式的演示图上把Factory类命名为Creator,下面的实现沿用了这个命名。
演示实现:
1)Factory.h
#ifndef FACTORY_H
#define FACTORY_H
class Product
{
public:
Product(){}
virtual ~Product(){}
};
class ConcreateProduct
: public Product
{
public:
ConcreateProduct();
virtual ~ConcreateProduct();
};
class Creator
{
public:
Creator(){}
virtual ~Creator(){}
void AnOperation();
protected:
virtual Product* FactoryMethod() = 0;
};
class ConcreateCreator
: public Creator
{
public:
ConcreateCreator();
virtual ~ConcreateCreator();
protected:
virtual Product* FactoryMethod();
};
#endif
2)Factory.cpp
#include "Factory.h"
#include <iostream>
using namespace std;
ConcreateProduct::ConcreateProduct()
{
std::cout << "construction of ConcreateProduct\n";
}
ConcreateProduct::~ConcreateProduct()
{
std::cout << "destruction of ConcreateProduct\n";
}
void Creator::AnOperation()
{
Product* p = FactoryMethod();
std::cout << "an operation of product\n";
}
ConcreateCreator::ConcreateCreator()
{
std::cout << "construction of ConcreateCreator\n";
}
ConcreateCreator::~ConcreateCreator()
{
std::cout << "destruction of ConcreateCreator\n";
}
Product* ConcreateCreator::FactoryMethod()
{
return new ConcreateProduct();
}
3)Main.cpp(测试代码)
#include "Factory.h"
#include <stdlib.h>
int main(int argc,char* argv[])
{
Creator *p = new ConcreateCreator();
p->AnOperation();
delete p;
system("pause");
return 0;
}
2、Abstract Factory模式
作用:
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
UML结构图:
抽象基类:
1) ProductA,ProductB:分别代表不同类型的产品,而它们的派生类则是这种产品的一个实现。
2) AbstractFactory:生产这一系列产品的一个抽象工厂,它的派生类是不同的实现。
接口函数:
AbstractFactory::CreateProductA和AbstractFactory::CreateProductB:分别是生产不同产品的不同的实现,由各个派生出来的抽象工厂实现之。
解析:
Abstract Factory 模式和Factory最大的差别就是抽象工厂创建的是一系列相关的对象,其中创建的实现其实采用的就是Factory模式的方法,对于某个实现有一个派生出来的抽象工厂,另一个实现有另一个派生出来的工厂等等。
抽象工厂需要特别注意的地方就是区分不同类型的产品和这些产品的不同实现。显而易见的,如果有n种产品同时有m中不同的实现,那么根据乘法原理可知有n*m个Factory模式的使用。
实现:
1)AbstractFactory.h
#ifndef ABSTRACTFACTORY_H
#define ABSTRACTFACTORY_H
// 抽象基类 AbstractProductA,代表产品 A 的抽象
class AbstractProductA
{
public:
AbstractProductA() {}
virtual ~AbstractProductA(){};
};
// 派生类 ConcreateProductA1,继承自 AbstractProductA,代表产品 A 的第一种实现
class ConcreateProductA1
: public AbstractProductA
{
public:
ConcreateProductA1();
virtual ~ConcreateProductA1();
};
// 派生类 ConcreateProductA2,继承自 AbstractProductA,代表产品 A 的第二种实现
class ConcreateProductA2
: public AbstractProductA
{
public:
ConcreateProductA2();
virtual ~ConcreateProductA2();
};
// 抽象基类 AbstractProductB,代表产品 B 的抽象
class AbstractProductB
{
public:
AbstractProductB() {}
virtual ~AbstractProductB(){};
};
// 派生类 ConcreateProductB1,继承自 AbstractProductB,代表产品 B 的第一种实现
class ConcreateProductB1
: public AbstractProductB
{
public:
ConcreateProductB1();
virtual ~ConcreateProductB1();
};
// 派生类 ConcreateProductB2,继承自 AbstractProductB,代表产品 B 的第二种实现
class ConcreateProductB2
: public AbstractProductB
{
public:
ConcreateProductB2();
virtual ~ConcreateProductB2();
};
// 抽象基类 AbstractFactory,工厂的抽象类,生产产品 A 和产品 B
class AbstractFactory
{
public:
AbstractFactory(){}
virtual ~AbstractFactory(){}
virtual AbstractProductA* CreateProductA() = 0;
virtual AbstractProductB* CreateProductB() = 0;
};
// 派生类 ConcreateFactory1,继承自 AbstractFactory
// 生产产品 A 和产品 B 的第一种实现
class ConcreateFactory1
: public AbstractFactory
{
public:
ConcreateFactory1();
virtual ~ConcreateFactory1();
virtual AbstractProductA* CreateProductA();
virtual AbstractProductB* CreateProductB();
};
// 派生类 ConcreateFactory2,继承自 AbstractFactory
// 生产产品 A 和产品 B 的第二种实现
class ConcreateFactory2
: public AbstractFactory
{
public:
ConcreateFactory2();
virtual ~ConcreateFactory2();
virtual AbstractProductA* CreateProductA();
virtual AbstractProductB* CreateProductB();
};
#endif
2)AbstractFactory.cpp
#include <iostream>
#include "AbstractFactory.h"
ConcreateProductA1::ConcreateProductA1()
{
std::cout << "construction of ConcreateProductA1\n";
}
ConcreateProductA1::~ConcreateProductA1()
{
std::cout << "destruction of ConcreateProductA1\n";
}
ConcreateProductA2::ConcreateProductA2()
{
std::cout << "construction of ConcreateProductA2\n";
}
ConcreateProductA2::~ConcreateProductA2()
{
std::cout << "destruction of ConcreateProductA2\n";
}
ConcreateProductB1::ConcreateProductB1()
{
std::cout << "construction of ConcreateProductB1\n";
}
ConcreateProductB1::~ConcreateProductB1()
{
std::cout << "destruction of ConcreateProductB1\n";
}
ConcreateProductB2::ConcreateProductB2()
{
std::cout << "construction of ConcreateProductB2\n";
}
ConcreateProductB2::~ConcreateProductB2()
{
std::cout << "destruction of ConcreateProductB2\n";
}
ConcreateFactory1::ConcreateFactory1()
{
std::cout << "construction of ConcreateFactory1\n";
}
ConcreateFactory1::~ConcreateFactory1()
{
std::cout << "destruction of ConcreateFactory1\n";
}
AbstractProductA* ConcreateFactory1::CreateProductA()
{
return new ConcreateProductA1();
}
AbstractProductB* ConcreateFactory1::CreateProductB()
{
return new ConcreateProductB1();
}
ConcreateFactory2::ConcreateFactory2()
{
std::cout << "construction of ConcreateFactory2\n";
}
ConcreateFactory2::~ConcreateFactory2()
{
std::cout << "destruction of ConcreateFactory2\n";
}
AbstractProductA* ConcreateFactory2::CreateProductA()
{
return new ConcreateProductA2();
}
AbstractProductB* ConcreateFactory2::CreateProductB()
{
return new ConcreateProductB2();
}
3)Main.cpp(测试代码)
#include "AbstractFactory.h"
#include <stdlib.h>
int main()
{
// 生产产品 A 的第一种实现
ConcreateFactory1 *pFactory1 = new ConcreateFactory1;
AbstractProductA *pProductA = pFactory1->CreateProductA();
// 生产产品 B 的第二种实现
ConcreateFactory2 *pFactory2 = new ConcreateFactory2;
AbstractProductB *pProductB = pFactory2->CreateProductB();
delete pFactory1;
delete pProductA;
delete pFactory2;
delete pProductB;
system("pause");
return 0;
}
讨论
AbstractFactory模式和Factory模式的区别是初学(使用)设计模式时候的一个容易引起困惑的地方。实际上,AbstractFactory 模式是为创建一组(有多类)相关或依赖的对象提供创建接口,而Factory模式正如我在相应的文档中分析的是为一类对象提供创建接口或延迟对象的创建到子类中实现。并且可以看到,AbstractFactory模式通常都是使用Factory模式实现。
实验二 Adapter模式
[实验目的]
掌握Adapter模式的意图及其代码实现。
[实验内容]
用C++语言实现Adapter模式。
[实验要点及说明]
Adapter模式的作用:
将一个类的接口转换成客户希望的另外一个接口。Adapt模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
UML示意图
1)采用继承原有接口类的方式
2)采用组合原有接口类的方式
解析:
Adapt 模式其实就是把完成同样的一个功能但是接口不能兼容的类桥接在一起使之可以在一起工作,这个模式使得复用旧的接口成为可能。
实现:
Adapt 模式有两种实现办法,一种是采用继承原有接口类的方法,一种是采用组合原有接口类的方法,这里采用的是第二种实现方法。
1)Adapt.h
#ifndef ADAPTER_H
#define ADAPTER_H
// 需要被 Adapt 的类
class Target
{
public:
Target(){}
virtual ~Target() {}
virtual void Request() = 0;
};
// 与被 Adapt 对象提供不兼容接口的类
class Adaptee
{
public:
Adaptee(){}
~Adaptee(){}
void SpecialRequest();
};
// 进行 Adapt 的类,采用聚合原有接口类的方式
class Adapter
: public Target
{
public:
Adapter(Adaptee* pAdaptee);
virtual ~Adapter();
virtual void Request();
private:
Adaptee* m_pAdptee;
};
#endif
2)Adapt.cpp
#include "Adapter.h"
#include <iostream>
void Adaptee::SpecialRequest()
{
std::cout << "SpecialRequest of Adaptee\n";
}
Adapter::Adapter(Adaptee* pAdaptee)
: m_pAdptee(pAdaptee)
{
}
Adapter::~Adapter()
{
delete m_pAdptee;
m_pAdptee = NULL;
}
void Adapter::Request()
{
std::cout << "Request of Adapter\n";
m_pAdptee->SpecialRequest();
}
3)Main.cpp
#include "Adapter.h"
#include <stdlib.h>
int main()
{
Adaptee *pAdaptee = new Adaptee;
Target *pTarget = new Adapter(pAdaptee);
pTarget->Request();
delete pTarget;
system("pause");
return 0;
}
实验三 Observer模式
[实验目的]
掌握Observer模式的意图及其代码实现。
[实验内容]
用C++语言实现Observer模式。
[实验要点及说明]
Observer模式的作用:
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
UML 结构图:
解析:
Observer模式定义的是一种一对多的关系,这里的一就是图中的Subject类,而多则是Observer类。当Subject类的状态发生变化的时候通知与之对应的Observer类也去相应的更新状态,同时支持动态的添加和删除Observer对象的功能。
Observer模式的实现要点是:第一,一般subject类都是采用链表等容器来存放Observer对象;第二抽取出Observer对象的一些公共的属性形成Observer基类,而Subject中保存的则是Observer类对象的指针,这样就使Subject和具体的Observer实现了解耦,也就是Subject不需要去关心到底是哪个Observer对放进了自己的容器中。生活中有很多例子可以看作是Observer模式的运用,比方说,一个班有一个班主任(Subject),他管理手下的一帮学生(Observer),当班里有一些事情发生需要通知学生的时候,班主任要做的不是逐个学生挨个的通知,而是把学生召集起来一起通知,实现了班主任和具体学生的关系解耦。
实现:
1)Observer.h
#ifndef OBSERVER_H
#define OBSERVER_H
#include <list>
typedef int STATE;
class Observer;
// Subject 抽象基类,只需要知道 Observer 基类的声明就可以了
class Subject
{
public:
Subject() : m_nSubjectState(-1){}
virtual ~Subject();
void Notify(); // 通知对象改变状态
void Attach(Observer *pObserver); // 新增对象
void Detach(Observer *pObserver); // 删除对象
// 虚函数,提供默认的实现,派生类可以自己实现来覆盖基类的实现
virtual void SetState(STATE nState); // 设置状态
virtual STATE GetState(); // 得到状态
protected:
STATE m_nSubjectState; // 模拟保存 Subject 状态的变量
std::list<Observer*> m_ListObserver; // 保存 Observer 指针的链表
};
// Observer 抽象基类
class Observer
{
public:
Observer() : m_nObserverState(-1){}
virtual ~Observer(){}
// 纯虚函数,各个派生类可能有不同的实现
// 通知 Observer 状态发生了变化
virtual void Update(Subject* pSubject) = 0;
protected:
STATE m_nObserverState; // 模拟保存 Observer 状态的变量
};
// ConcreateSubject 类,派生在 Subject 类
class ConcreateSubject
: public Subject
{
public:
ConcreateSubject() : Subject(){}
virtual ~ConcreateSubject(){}
// 派生类自己实现来覆盖基类的实现
virtual void SetState(STATE nState); // 设置状态
virtual STATE GetState(); // 得到状态
};
// ConcreateObserver 类派生自 Observer
class ConcreateObserver
: public Observer
{
public:
ConcreateObserver() : Observer(){}
virtual ~ConcreateObserver(){}
// 虚函数,实现基类提供的接口
virtual void Update(Subject* pSubject);
};
#endif
2)Observer.cpp
#include "Observer.h"
#include <iostream>
#include <algorithm>
// Subject 类成员函数的实现
void Subject::Attach(Observer *pObserver)
{
std::cout << "Attach an Observer\n";
m_ListObserver.push_back(pObserver);
}
void Subject::Detach(Observer *pObserver)
{
std::list<Observer*>::iterator iter;
iter = std::find(m_ListObserver.begin(), m_ListObserver.end(), pObserver);
if (m_ListObserver.end() != iter)
{
m_ListObserver.erase(iter);
}
std::cout << "Detach an Observer\n";
}
void Subject::Notify()
{
std::cout << "Notify Observers's State\n";
std::list<Observer*>::iterator iter1, iter2;
for (iter1 = m_ListObserver.begin(), iter2 = m_ListObserver.end();
iter1 != iter2;
++iter1)
{
(*iter1)->Update(this);
}
}
void Subject::SetState(STATE nState)
{
std::cout << "SetState By Subject\n";
m_nSubjectState = nState;
}
STATE Subject::GetState()
{
std::cout << "GetState By Subject\n";
return m_nSubjectState;
}
Subject::~Subject()
{
std::list<Observer*>::iterator iter1, iter2, temp;
for (iter1 = m_ListObserver.begin(), iter2 = m_ListObserver.end();
iter1 != iter2;
)
{
temp = iter1;
++iter1;
delete (*temp);
}
m_ListObserver.clear();
}
// ConcreateSubject 类成员函数的实现
void ConcreateSubject::SetState(STATE nState)
{
std::cout << "SetState By ConcreateSubject\n";
m_nSubjectState = nState;
}
STATE ConcreateSubject::GetState()
{
std::cout << "GetState By ConcreateSubject\n";
return m_nSubjectState;
}
// ConcreateObserver 类成员函数的实现
void ConcreateObserver::Update(Subject* pSubject)
{
if (NULL == pSubject)
return;
m_nObserverState = pSubject->GetState();
std::cout << "The ObeserverState is " << m_nObserverState << std::endl;
}
3)Main.cpp
#include "Observer.h"
#include <iostream>
int main()
{
Observer *p1 = new ConcreateObserver;
Observer *p2 = new ConcreateObserver;
Subject* p = new ConcreateSubject;
p->Attach(p1);
p->Attach(p2);
p->SetState(4);
p->Notify();
p->Detach(p1);
p->SetState(10);
p->Notify();
delete p;
system("pause");
return 0;
}
实验四 Interpreter模式
[实验目的]
掌握Interpreter模式的意图及其代码实现。
[实验内容]
用C++语言实现Interpreter模式。
[实验要点及说明]
Interpreter模式的作用:
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
Interpreter模式典型的结构图为:
解析:
Interpreter 模式中,提供了Terminal Expression和Nonterminal Expression两种表达式的解释方式,Context类用于为解释过程提供一些附加的信息(例如全局的信息)。
实现:
代码片断1:Context.h
//Context.h
#ifndef _CONTEXT_H_
#define _CONTEXT_H_
class Context
{
public:
Context();
~Context();
protected:
private:
};
#endif //~_CONTEXT_H_
代码片断2:Context.cpp
//Context.cpp
#include "Context.h"
Context::Context()
{
}
Context::~Context()
{
}
代码片断3:Interpret.h
//Interpret.h
#ifndef _INTERPRET_H_
#define _INTERPRET_H_
#include "Context.h"
#include <string>
using namespace std;
class AbstractExpression
{
public:
virtual ~AbstractExpression();
virtual void Interpret(const Context& c);
protected:
AbstractExpression();
private:
};
class TerminalExpression:public AbstractExpression
{
public:
TerminalExpression(const string& statement);
~ TerminalExpression();
void Interpret(const Context& c);
protected:
private:
string _statement;
};
class NonterminalExpression:public AbstractExpression
{
public:
NonterminalExpression(AbstractExpression* expression,int times);
~ NonterminalExpression();
void Interpret(const Context& c);
protected:
private:
AbstractExpression* _expression;
int _times;
};
#endif //~_INTERPRET_H_
代码片断4:Interpret.cpp
//interpret.cpp
#include "Interpret.h"
#include <iostream>
using namespace std;
AbstractExpression::AbstractExpression()
{
}
AbstractExpression::~AbstractExpression()
{
}
void AbstractExpression::Interpret(const Context& c)
{
}
TerminalExpression::TerminalExpression(const string& statement)
{
this->_statement = statement;
}
TerminalExpression::~TerminalExpression()
{
}
void TerminalExpression::Interpret(const Context& c)
{
cout<<this->_statement<<" TerminalExpression"<<endl;
}
NonterminalExpression::NonterminalExpression(AbstractExpression*expression, int times)
{
this->_expression = expression;
this->_times = times;
}
NonterminalExpression::~NonterminalExpression()
{
}
void NonterminalExpression::Interpret(const Context& c)
{
for (int i = 0; i < _times ; i++)
{
this->_expression->Interpret(c);
}
}
代码片断5:main.cpp
//main.cpp
#include "Context.h"
#include "Interpret.h"
#include <iostream>
using namespace std;
int main(int argc,char* argv[])
{
Context* c = new Context();
AbstractExpression* te = new TerminalExpression("hello");
AbstractExpression* nte = new NonterminalExpression(te,2);
nte->Interpret(*c);
return 0;
}