设计模式研究(一)实例比较TemplateMethod与Strategy
设计模式研究(二)-Singleton
本文要讨论的是代理和适配器模式。
两种模式理念上的差别
代理(Proxy)模式给某一个对象提供一个代理,并由代理对象控制对原对象的引用。

适配器模式(Adapter)把一个类的接口变换成客户端所期待的另一种接口,从而使原本接口不匹配而无法在一起工作的两个类能够在一起工作。

Proxy的关注点是职能转移,引入代理层代替目标端与调用端进行沟通,而且代理层和目标端具有相同的服务结构(继承同一个接口)。
Adapter的关注点是接口变换,引入一个符合调用端要求的“转化器”实现目标端与调用端的沟通,而且转化器和目标端的服务结构式是不一样的。
实例说明
对于外出打工或外出求学的游子们,大多都有过年回家买车票的经历。下面用代理模式还原一下独具特色的买车票经历。
先抽象一个火车票接口
<!-- <br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->
//
火车票
public
interface
ITicket
{
string
Buy(
int
price);
//
车票不紧张的情况下适用
string
Buy(
int
price,EnumIdentityidentity);
//
车票紧张或购票需求量大的情况下适用
}
//
购票人身份
public
enum
EnumIdentity
{
外出务工人员
=
0
,
黄牛
=
1
,
}
下面是火车站售票系统
<!-- <br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->
//
火车站售票系统
public
class
RailwayStation:ITicket
{
public
string
Buy(
int
price)
{
string
result
=
string
.Empty;
result
=
"
票价:
"
+
price;
return
result;
}
public
string
Buy(
int
price,EnumIdentityidentity)
{
string
result
=
string
.Empty;
if
(identity
==
EnumIdentity.黄牛)
result
=
"
票价:
"
+
price;
if
(identity
==
EnumIdentity.外出务工人员)
result
=
"
车票已售完
"
;
return
result;
}
}
看来“外出务工人员”在车票紧张的情况下从火车站是拿不到车票的,职能上作为火车站售票窗口代理的“黄牛”应用而生了!
<!-- <br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->
//
黄牛售票
public
class
Scalper:ITicket
{
ITicketTicket
=
new
RailwayStation();
public
string
Buy(
int
price)
{
string
result
=
string
.Empty;
result
=
"
暂不受理
"
;
return
result;
}
public
string
Buy(
int
price,EnumIdentityidentity)
{
string
result
=
"
手续费:
"
+
price
*
0.2
;
result
+=
Ticket.Buy(price,EnumIdentity.黄牛);
return
result;
}
}
下面是买票场景重现:
<!-- <br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->
//
外出务工人员过节回家
public
class
ProxyClient
{
public
static
void
Call()
{
//
票价
int
price
=
100
;
string
result
=
string
.Empty;
ITicketTicket1
=
new
RailwayStation();
result
=
Ticket1.Buy(price,EnumIdentity.外出务工人员);
Console.WriteLine(
"
去火车站买票:
"
+
result);
ITicketTicket2
=
new
Scalper();
result
=
Ticket2.Buy(price,EnumIdentity.外出务工人员);
Console.WriteLine(
"
和黄牛买票:
"
+
result);
}
}

再说一个我的亲身经历,很久以前,笔记本的键盘出现串键现象,于是想外接一个键盘来用。一天,正好看到京东上一款非常便宜而且评价很不错的键盘在做促销。似乎没有太多考虑就下了订单,键盘送到家以后,想起了漩涡鸣人常说的一个词 “纳尼?”,是PS/2口的!
<!-- <br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->
//
PS/2接口
public
interface
IPS2
{
void
PS2Connect();
}
//
PS/2接口的键盘
public
class
keyboard:IPS2
{
public
void
PS2Connect()
{
Console.WriteLine(
"
PS/2接口类型的键盘已经连接到电脑
"
);
}
}
我的笔记本只能用USB口的。
<!-- <br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->
//
USB接口
public
interface
IUSB
{
void
USBConnect();
}
怎么办?幸好有这种东西:PS/2 to USB converter 。

<!-- <br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->
//
引入适配器PS/2toUSB转化器
public
class
Adapter:keyboard,IUSB
{
public
void
USBConnect()
{
this
.PS2Connect();
}
}
现在可以享用新键盘了!
<!-- <br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->
//
一台不支持PS/2接口,但支持USB接口的主机
public
class
AdapterClient
{
public
static
void
Call()
{
//
主机与转化器连接
IUSBusb
=
new
Adapter();
usb.USBConnect();
}
}
