设计模式研究(三)Proxy与Adapter

设计模式研究(一)实例比较TemplateMethod与Strategy

设计模式研究(二)-Singleton 

本文要讨论的是代理和适配器模式。

两种模式理念上的差别

代理(Proxy)模式给某一个对象提供一个代理,并由代理对象控制对原对象的引用。 

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

 

 Proxy的关注点是职能转移,引入代理层代替目标端与调用端进行沟通,而且代理层和目标端具有相同的服务结构(继承同一个接口)。

Adapter的关注点是接口变换,引入一个符合调用端要求的“转化器”实现目标端与调用端的沟通,而且转化器和目标端的服务结构式是不一样的。

 实例说明

 对于外出打工或外出求学的游子们,大多都有过年回家买车票的经历。下面用代理模式还原一下独具特色的买车票经历。

 先抽象一个火车票接口

    //火车票
    public interface ITicket
    {
        
string Buy(int price);//车票不紧张的情况下适用
        string Buy(int price, EnumIdentity identity);//车票紧张或购票需求量大的情况下适用
    }
    
//购票人身份
    public enum EnumIdentity
    {
        外出务工人员 
= 0,
        黄牛 
= 1,
    }

下面是火车站售票系统

    //火车站售票系统
    public class RailwayStation : ITicket
    {
        
public string Buy(int price) 
        {
            
string result = string.Empty;
            result 
= "票价:" + price;
            
return result;
        }
        
public string Buy(int price, EnumIdentity identity)
        {
            
string result = string.Empty;
            
if (identity == EnumIdentity.黄牛)
                result 
= "票价:" + price;
            
if (identity == EnumIdentity.外出务工人员)
                result 
= "车票已售完";
            
return result;
        }
    }

看来“外出务工人员”在车票紧张的情况下从火车站是拿不到车票的,职能上作为火车站售票窗口代理的“黄牛”应用而生了!

    //黄牛售票
    public class Scalper:ITicket
    {
        ITicket Ticket 
= new RailwayStation();
        
public string Buy(int price)
        {
            
string result = string.Empty;
            result 
= "暂不受理";
            
return result;
        }
        
public string Buy(int price, EnumIdentity identity)
        {
            
string result = "手续费:" + price * 0.2;
            result 
+= Ticket.Buy(price, EnumIdentity.黄牛);
            
return result;
        }
    }

下面是买票场景重现:

    //外出务工人员过节回家
    public class ProxyClient
    {
        
public static void Call()
        {
            
//票价
            int price = 100;
            
string result = string.Empty;
            ITicket Ticket1 
= new RailwayStation();
            result 
= Ticket1.Buy(price, EnumIdentity.外出务工人员);
            Console.WriteLine(
"去火车站买票:" + result);

            ITicket Ticket2 
= new Scalper();
            result 
= Ticket2.Buy(price, EnumIdentity.外出务工人员);
            Console.WriteLine(
"和黄牛买票:" + result);

        }
    }

再说一个我的亲身经历,很久以前,笔记本的键盘出现串键现象,于是想外接一个键盘来用。一天,正好看到京东上一款非常便宜而且评价很不错的键盘在做促销。似乎没有太多考虑就下了订单,键盘送到家以后,才发现是PS/2口的!

    //PS/2接口
    public interface IPS2
    {
        
void PS2Connect();
    }
    
//PS/2接口的键盘
    public class keyboard:IPS2
    {
        
public void PS2Connect()
        {
            Console.WriteLine(
"PS/2接口类型的键盘已经连接到电脑");
        }
    }

我的笔记本只能用USB口的。

    //USB接口
    public interface IUSB
    {
        
void USBConnect();
    }

怎么办?幸好有这种东西:PS/2 to USB converter 。

 

    //引入适配器   PS/2 to USB转化器
    public class Adapter : keyboard, IUSB
    {
        
public void USBConnect()
        {
            
this.PS2Connect();
        }
    }

现在可以享用新键盘了!

// 一台不支持PS/2接口,但支持USB接口的主机
    public class AdapterClient
    {
        
public static void Call()
        {
            
//主机与转化器连接
            IUSB usb = new Adapter();
            usb.USBConnect();
        }
    }

 

 

 

 

posted @ 2010-08-25 08:39  青羽  阅读(2659)  评论(10编辑  收藏  举报