Head First 设计模式 Design Pattern 附录 Bridge, Builder, Chain, Flyweight, Interpreter

本文介绍了桥接模式、生成器模式、责任链模式、蝇量模式和解释器模式等五种设计模式,每种模式都提供了详细的优缺点分析及应用场景,并通过示例代码展示了其实现方式。

附录A: 余下的模式

1桥接 Bridge 不只改变实现, 也改变抽象

>优点 将实现解耦 让其和UI之间不再绑定; 抽象和实现可以独立扩展互不影响; 对于"具体的抽象类"所做的改变不影响客户

>用途和缺点 适合需要跨越多个平台的图形和窗口系统上; 当需要用不同的方式改变接口和实现时; 增加了复杂度;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//***********Bridge***********
class ITVImp
{
public:
    virtual void onImp() = 0;
};
                                                                          
class IRemoteControl
{
public:
    virtual void on() = 0;
    virtual void SetImp(ITVImp* pImp) { mpImp = pImp; }
    virtual ITVImp* GetImp() { return mpImp;}
private:
    ITVImp* mpImp;
};
                                                                      
class RCAImp : public ITVImp
{
public:
    virtual void onImp();
};
                                                                      
class ConcreteRemoteControl : public IRemoteControl
{
public:
    ConcreteRemoteControl();
    virtual void on();
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void RCAImp::onImp()
{
    cout << "RCAImp" << endl;
}
                                                                     
ConcreteRemoteControl::ConcreteRemoteControl()
{
    SetImp(new RCAImp());
}
                                                                     
void ConcreteRemoteControl::on()
{
    ((RCAImp*)GetImp())->onImp();
}
                                                                     
        //Bridge
        ConcreteRemoteControl* control = new ConcreteRemoteControl();
        control->on();

PIMPL模式 Private Class Data Pattern 隐藏类的内部实现和数据 用户只能看到public API

2生成器 Builder 封装一个产品的构造过程 允许按步骤构造

>优点 将复杂对象的创建过程封装起来; 允许对象通过多个步骤创建 可以改变过程(工厂模式只有一个步骤); 向客户隐藏产品内部的表现; 产品的表现可替换 客户只看到抽象的接口

>用途和缺点 创建组合结构; 与工厂模式相比 采用生成器创建对象的客户需要具备更多领域知识;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//***********Builder***********
class Result
{
public:
    void show();
    string sPartA;
    string sPartB;
};
                                                  
class IBuilder
{
public:
    virtual void buildA(string a) = 0;
    virtual void buildB(string b) = 0; //...
    virtual Result* getResult() = 0;
};
                                                  
class ResBuilder : public IBuilder
{
public:
    ResBuilder();
    virtual void buildA(string a);
    virtual void buildB(string b);
    virtual Result* getResult() { return mpRes;};
private:
    Result* mpRes;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
ResBuilder::ResBuilder()
{
    mpRes = new Result();
}
                                                  
void ResBuilder::buildA(string a)
{
    mpRes->sPartA = a;
}
                                                  
void ResBuilder::buildB(string b)
{
    mpRes->sPartB = b;
}
                                                  
void Result::show()
{
    cout << sPartA + sPartB << endl;
}
                                                  
        //Builder
        ResBuilder* builder = new ResBuilder();
        builder->buildA("Build part A");
        builder->buildB("Build part B");
        Result* res = builder->getResult();
        res->show();


3责任链 Chain of Responsibility 让一个以上的对象处理某个请求的时候

>优点 将请求的发送者和接收者解耦; 简化对象 使其不需要知道链的结构; 通过改变链内的成员或调动次序 允许动态新增或者删除责任

>用途和缺点 经常使用在窗口系统中 处理鼠标和键盘事件; 不保证请求一定会被执行; 不容易观察运行时的特征, 不易查错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//***********ChainOR***********
class IHandler;
typedef vector <IHandler*> HANDLERVEC;
class IHandler
{
public:
    IHandler(int iType) : miType(iType) {};
    virtual void handleRequest() = 0;
    virtual int getType() {return miType;}
private:
    int miType;
};
                                      
class ConcreteHandler : public IHandler
{
public:
    ConcreteHandler(int iType);
    virtual void handleRequest();
private:
    HANDLERVEC mHandlerVec;
};
                                      
class HandlerLev1 : public IHandler
{
public:
    HandlerLev1(int iType) : IHandler(iType) {};
    virtual void handleRequest() {cout << "Handle Level1" << endl;};
};
                                      
class HandlerLev2 : public IHandler
{
public:
    HandlerLev2(int iType) : IHandler(iType) {};
    virtual void handleRequest() {cout << "Handle Level2" << endl;};
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
ConcreteHandler::ConcreteHandler(int iType) : IHandler(iType)
{
    HandlerLev1* lev1 =  new HandlerLev1(1);
    HandlerLev2* lev2 =  new HandlerLev2(2);
    mHandlerVec.push_back(lev1);
    mHandlerVec.push_back(lev2);
}
                                     
void ConcreteHandler::handleRequest()
{
    HANDLERVEC::iterator iter = mHandlerVec.begin();
    for (; iter != mHandlerVec.end(); iter++)
    {
        IHandler* handler = *iter;
        if (handler != NULL && getType() == handler->getType())
        {
            handler->handleRequest();
            return;
        }
    }
}
        //ChainOR
        ConcreteHandler* handler = new ConcreteHandler(1);
        handler->handleRequest();


4蝇量 Flyweight 让某个类的一个实例能用来提供很多"虚拟实例" 

>优点 减少运行时对象实例的个数 节省内存; 将许多"虚拟对象"的状态集中管理

>用途和缺点 当类有许多的实例 这些实例能被同一个方法控制的时候; 单个的逻辑实例将无法拥有独立而不同的行为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//***********Flyweight***********
class Tree
{
public:
    Tree(int i);
    virtual void display(int x, int y);
    virtual int getAge() { return miAge;}
private:
    int miAge;
};
                         
struct TreeData
{
    int xCoord;
    int yCoord;
    int age;
};
                         
typedef map <int, Tree*> TREEMAP;
class TreeManager
{
public:
    void displayTrees(int num, TreeData data[]);
    Tree* getTree(int age);
private:
    TREEMAP treeMap;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
Tree::Tree(int i) : miAge(i) {}
                        
void Tree::display(int x, int y)
{
    cout<< "Coord"<< x << ","<< y <<
    "Age"<<miAge<<endl;
}
                        
void TreeManager::displayTrees(int num, TreeData data[])
{
    for(int i = 0; i < num; i++)
    {
        TreeData treeData = data[i];
        getTree(treeData.age)->display(treeData.xCoord, treeData.yCoord);
    }
}
                        
Tree* TreeManager::getTree(int age)
{
    Tree* tree;
    TREEMAP::iterator iter = treeMap.find(age);
    if (iter == treeMap.end()) // Save the memeory
    {
        tree = new Tree(age);
        cout<<"new a tree"<<endl;
        treeMap[age] = tree;
    }
    else
        tree = treeMap[age];
                            
    return tree;
}
        //Flyweight
        TreeData treeData[3] =
        {
            {10, 20, 3},
            {20, 10, 5},
            {30, 30, 3}
        };
        TreeManager treeManager;
        treeManager.displayTrees(3, treeData);


5解释器 Interpreter 为语言创建解释器

>优点 将每一个语法规则表示成一个类; 语法由许多类表示 容易改变或扩展语言; 通过在类结构中加入新的方法 可以在解释的同时增加新的行为 例如格式美化或程序验证

>用途和缺点 需要实现一个简单的语言时; 有一个简单的语法 简单比效率更重要时; 处理脚本语言和编程语言; 当语法规则数目过大时 模式将变得非常繁复 这种情况下适合解析器/编译器


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//***********Interpreter***********
class Context
{
public:
    Context(string s, int d) : statement(s), data(d) {};
    string getState() { return statement;}
    int getData() { return data;}
private:
    string statement;
    int data;
};
             
class IExpression
{
public:
    virtual void Interpreter(Context context) = 0;
};
             
class Expression : public IExpression
{
public:
    void Interpreter(Context context);
    void parseState(string);
    void parseData(int);
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void Expression::Interpreter(Context context)
{
    parseState(context.getState());
    parseData(context.getData());
}
            
void Expression::parseState(string s)
{
    cout << "string: " << s << endl;
}
            
void Expression::parseData(int d)
{
    cout << "data: " << d << endl;
}
        //Interpreter
        Context context("test", 1);
        Expression expression;
        expression.Interpreter(context);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值