design pattern--bridge

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// bridge.cpp : Defines the entry point for the console application.
//
/// author : chillyc
/// email : chillycreator @t gmail.com
/// uml:
/// _
/// / \
/// /_ _\
#include<iostream>
namespace pattern{
/// why use bridge pattern?
/// If the original parent class is not suitable for being inherited by subclass,
/// it will be refactor. And If there are some concepts are common,
/// it will be abstracted as implement interface or abstract class.
/// for example: in KFC, there will be some softdrink to be sold,
/// like coca cola, coff, and so on. And if you wish, you will add some additions like sugar,
/// or ice into softdrinks. If we design the classes as sugar-cocacola, sugar-coff, ice-cocacola,
/// and ice-coff. There will be four subclasses here. And in the future, is there add another
/// additions? If yes, the system will add another two classes! But if use bridge pattern,
/// it will add only one class called "another additions" inherited from addition class.
/// This is benefits of this pattern.
#ifndef ADDITION_H
#define ADDITION_H
/// this is the implement class in Bridge pattern.
/// if you want add another additions,
/// inherit this class and the point of your class into Softdrink class.
/// Do you have better implements for just adding class here and not modifying Softdrink class?
class Addition{
public:
virtual void Add()=0;
virtual ~Addition(){};
};
#endif
#ifndef SUGAR_H
#define SUGAR_H
class Sugar:public Addition{
public:
virtual void Add();
};
#endif
void Sugar::Add(){
std::cout<<"add sugar"<<std::endl;
}
#ifndef ICE_H
#define ICE_H
class Ice:public Addition{
public:
virtual void Add();
};
#endif
void Ice::Add(){
std::cout<<"add ice"<<std::endl;
}
#ifndef SOFTDRINK_H
#define SOFTDRINK_H
/// this class is the abstract class in Bridge pattern.
/// I consider there will be some other implement methods.
/// I use Addition objects as member variables,
/// and construct and destroy them in Softdrink.
/// But if there is no member variables of Addition, It will be ok.
/// for example: you can send Addition instances as parameters into Softdrink subclass.
/// But in Bridge pattern, the uml is aggregation between implement class and abstract class.
class Softdrink{
public:
Softdrink();
virtual void drink()=0;
virtual ~Softdrink()=0;
protected:
Addition *sugar;
Addition *ice;
/// another additions add here!
};
Softdrink::~Softdrink(){
if(NULL != sugar){
delete sugar;
}
if(NULL != ice){
delete ice;
}
}
Softdrink::Softdrink(){
sugar = new Sugar();
ice = new Ice();
}
#endif
#ifndef COFF_H
#define COFF_H
class Coff: public Softdrink{
public:
virtual void drink();
};
#endif
void Coff::drink(){
std::cout<<"I am drinking coff!"<<std::endl;
sugar->Add();
}
#ifndef COCA_H
#define COCA_H
class Coca: public Softdrink{
public:
virtual void drink();
};
#endif
void Coca::drink(){
std::cout<<"I am drinking coca cola!"<<std::endl;
ice->Add();
}
}
int main()
{
pattern::Coca coca;
coca.drink();
pattern::Coff coff;
coff.drink();
return 0;
}