**侯捷老师的C++笔记4**
设计模式
Delegation + Inheritance
—>Observer
- e.g.
Subject
<>—>Observer
<|—-Observer1, Observer2...
- 多个分屏,多个软件打开同一个文件
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
55class Subject
{
int m_value;
vector<Observer*> m_views; // 多个observer放到vector容器中
public:
// attach each Observer to Subject
void attach(Observer* obs)
{
m_views.push_bask(obs);
}
// if any changes, set the val and notify others
void set_val(int val)
{
m_value = value;
notify();
}
// update each view data
void notify()
{
for (int i = 0; i < m_views.size(); ++i)
m_views[i]->update(this, m_value);
}
};
class Observer
{
public void update(Subject* s);
};
class Observer1: public Observer1
{
int m_div;
public:
Observer1(Subject *model, int div)
{
model->attach(this);
}
void update(int v) {...}
};
class Observer2: public Observer1
{
int m_div;
public:
Observer2(Subject *model, int div)
{
model->attach(this);
}
void update(int v) {...}
};
{
Subject subj;
Observer1 o1(&subj, 4);
Observer2 o2(&subj, 4);
subj.set_val(14);
}
- e.g.
Delegation + Inheritance
—>Composite
Component
- 文件目录下既有可能是另一个目录,也有可能是一个文件
- 所以让文件和文件目录继承同一个父类, 文件目录中再委托这个父类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22class Component
{
int value;
public:
Component (int val) {value = val;}
virtual void add (Component*) {}
};
class Primitive: public Component
{
public:
Primitive(int val): Component(val) {}
};
class Composite: public Component
{
vector <Component*> c;
public:
Composite(int val): Component(val) {}
void add(Component* elem) {
c.push_bask(elem);
}
...
};
Delegation + Inheritance
—>Prototype
- 在不知道未来的子类会是什么的情况下使用, 不知道子类的名字
- 注:
- private
,+ public
,# protected
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
enum imageType
{
LAST, SPOT
};
class image
{
public:
virtual void draw() = 0; // pure virtual
static Image *findAndClone(imageType);
protected:
virtualimageType returnType() = 0;
virtual Image *clone() = 0;
static void addPrototype (Image *image)
{
_prototypes[_nextSlot++] = image;
}
private:
// addPrototype() saves each registered prototype here
static Image *_prototypes[10];
static int _nextSlot;
};
Image *Image::_prototypes[];
int Image::_nextSlot;
// client calls this public static member function when it needs an instance of an Image subclass
Image *Image::findAndClone(iamgeType type)
{
for (int i = 0; i < _nextSlot; i++)
{
if (_prototypes[i] -> returnType() == type)
return _prototypes[i]->clone();
}
}
// subclass:
class LandSatImage: public Image
{
public:
imageType returnType() { return LSAT; }
void draw() {
cout << "LandSatImage::draw" << _id << endl;
}
// when clone() is called, call the one_argument ctor with a dummy one_argument, otherwise it will call addPrototype() every time
Image *clone() {
return new LandSatImage(1);
}
protected:
LandSatImage(int dummy) { _id = _count++;}
private:
// Mechanism for initializing an Image subclass - this causes the
// default ctor to be called, which registers the subclass's prototype
static LandSatImage _landSatImage;
// this is only called when the private static member is initiated
LandSatImage() {
addPrototype(this);
}
int _id;
static int_count;
};
// Register the subclass's Prototype
LandSatImage LandSatImage::_landSatImage; // 调用private中的ctor
// Initialize the state per instance Mechanism
int LandSatImage::_count = 1;
.... other subclass
// simulated stream of creation requests
const int NUM_IMAGES = 8;
imageType imput[NUM_IMAGES] =
{
LSAT, LSAT, LSAT, SPOT, LSAT, SPOT, SPOT, LSAT
};
int main()
{
Image *images[NUM_IMAGES];
// given an image type, find the right prototype and return a clone
for (int i = 0; i < NUM_IMAGES; i++)
images[i] = Image::findAndClone(input[i]);
// demonstrate that correct iamge objects have been cloned
for (i = 0; i < NUM_IMAGES; i++)
images[i]->draw();
// free the dynamic memory
for (i = 0; i < NUM_IMAGES; i++)
delete images[i];
}
- 在不知道未来的子类会是什么的情况下使用, 不知道子类的名字