当DP遇见Py(十三) -- 适配器模式

目录
  1. 定义:
  2. 类图:
  3. 类型:结构型
  4. 实例:
    1. C++ 实现
    2. Python 实现
    3. Pythonic 实现
    4. 执行结果:
  5. Tips:

定义:

将一个类的接口转换为客户需要的另外一个接口。Adapter模式使得原本由于接口不兼容而不能在一起工作的那些类可以在一起工作。

类图:

类型:结构型

实例:

“在NBA,我需要翻译。” —— 姚明

C++ 实现

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
#include <iostream>
#include <string>
using namespace std;

class Player
{
public:
string name;
Player(string name)
{
this->name=name;
}
virtual void attack()=0;
virtual void defence()=0;
};

class Forwards:public Player
{
public:
Forwards(string name):Player(name){}
void attack()
{

cout<<name<<" 前锋进攻"<<endl;
}
void defence()
{

cout<<name<<" 前锋防守"<<endl;
}
};

class Center:public Player
{
public:
Center(string name):Player(name){}
void attack()
{

cout<<name<<" 中锋进攻"<<endl;
}
void defence()
{

cout<<name<<" 中锋防守"<<endl;
}
};

class Backwards:public Player
{
public:
Backwards(string name):Player(name){}
void attack()
{

cout<<name<<" 后卫进攻"<<endl;
}
void defence()
{

cout<<name<<" 后卫防守"<<endl;
}
};

class ForeignCenter
{
public:
string name;
ForeignCenter(string name)
{
this->name=name;
}
void myAttack()
{

cout<<name<<" 外籍中锋进攻"<<endl;
}
void myDefence()
{

cout<<name<<" 外籍后卫防守"<<endl;
}
};

class Translator:public Player
{
private:
ForeignCenter *fc;
public:
Translator(string name):Player(name)
{
fc=new ForeignCenter(name);
}
void attack()
{

fc->myAttack();
}
void defence()
{

fc->myDefence();
}
};

int main()
{

Player *p1=new Center("巴蒂尔");
p1->attack();
p1->defence();

Translator *tl=new Translator("姚明");
tl->attack();
tl->defence();

return 0;
}

Python 实现

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
# -*- coding=utf-8 -*-

class Player(object):
def __init__(self, name):
self._name = name
def attack(self):
raise NotImplementedError("Must Implement me")
def defence(self):
raise NotImplementedError("Must Implement me")

class Forwards(Player):
def __init__(self, name):
super(Forwards, self).__init__(name)
def attack(self):
print u'%s 前锋进攻' % self._name
def defence(self):
print u'%s 前锋防守' % self._name

class Center(Player):
def __init__(self, name):
super(Center, self).__init__(name)
def attack(self):
print u'%s 中锋进攻' % self._name
def defence(self):
print u'%s 中锋防守' % self._name

class ForeignCenter:
def __init__(self, name):
self._name = name
def myAttack(self):
print u'%s 外籍中锋进攻' % self._name
def myDefence(self):
print u'%s 外籍中锋防守' % self._name

class Translator(Player):
def __init__(self, name):
self._fc = ForeignCenter(name)
def attack(self):
self._fc.myAttack()
def defence(self):
self._fc.myDefence()

if __name__ == '__main__':
p1 = Center(u'巴蒂尔')
p1.attack()
p1.defence()

t1 = Translator(u'姚明')
t1.attack()
t1.defence()

Pythonic 实现

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
# -*- coding=utf-8 -*-

class Center:
def __init__(self, name):
self._name = name
def attack(self):
print u'%s 中锋进攻' % self._name
def defence(self):
print u'%s 中锋防守' % self._name

class ForeignCenter:
def __init__(self, name):
self._name = name
def myAttack(self):
print u'%s 外籍中锋进攻' % self._name
def myDefence(self):
print u'%s 外籍中锋防守' % self._name

class Adapter(object):
def __init__(self, adaptee, **adapted_methods):
self.adaptee = adaptee
self.__dict__.update(adapted_methods)

def __getattr__(self, attr):
return getattr(self.adaptee, attr)

if __name__ == '__main__':
players = []
players.append(Center(u'巴蒂尔'))
fc = ForeignCenter(u'姚明')
players.append(Adapter(fc, attack=fc.myAttack, defence=fc.myDefence))

for player in players:
player.attack()
player.defence()

执行结果:

1
2
3
4
巴蒂尔 中锋进攻
巴蒂尔 中锋防守
姚明 外籍中锋进攻
姚明 外籍中锋防守

Tips:

适配器模式Python实现没有什么特点,在这就不在赘述了。
Pythonic适配器模式的实现,充分运用了Python的特性,提供了一个高度抽象的适配器:Adapter。让我们看一下Adapter是如何实现: “将一个类的接口转换为客户需要的另外一个接口”的。

  • Adaptee 被适配的对象
  • adapted_methods 被适配的方法。由客户指定Adaptee的那些方法适配为客户需要的接口。如需要ForeignCenter对象的myAttack方法适配为客户所需要的attack接口。
  • **kwargs是一个正常的python字典类型,允许用户通过键值对来传递参数。如:attack=fc.myAttack, defence=fc.myDefence
  • __dict____getattr__是实现适配的关键。这里的主要作用是更新用户设置的适配方法(adapted_methods)到适配器(Adapter)的方法字典中,用户未设置的方法仍然使用被适配对象(adaptee)的方法。这两个东西是Python中面向对象的关键,在前面的帖子中已经介绍过了,在此不在赘述。

请找出上图中那个东东是“适配器”。

评论