舞步者

带她一起去周游世界
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

设计模式之五适配器(Adapter)方式

Posted on 2008-05-26 22:08  Kevin_Zhang  阅读(115)  评论(0)    收藏  举报
适配器在我们的现实生活中很常见,比如说随声听的编译器,二孔和三孔插入的转接器等等,所以我们今天讨论的适配器模式相对来说比较好理解
适配器的作用顾名思义就是让两个不能工作在一起的物件能兼容的在一起工作,其在两者之间其沟通协调的作用;对于我们这里的适配,大体也是这样的意思.
动机:
在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象”放在新的环境中使用,但是新环境要求的接口是这些现存对象所不满足的。
我们还是以之前一片文章所用的计算员工薪水为例,来说明适配器模式。
在我们已开发并测试完成的代码中,我们使用如下的计算薪水的方式,也即使用接口提供的CalculateSalary方法来计算:
 public abstract class Employee
    
{
        
public abstract void CalculateSalary();
    }

    
public class Engineer : Employee
    
{
        
public override void CalculateSalary()
        
{

        }

    }

    
public class Cleaner : Employee
    
{
        
public override void CalculateSalary()
        
{

        }

    }

    
public class Hr : Employee
    
{
        
public override void CalculateSalary()
        
{

        }

    }
但是,由于种种原因,我们计算员工薪水的方式得发生变化,使用新的接口提供的CalSalary方法,但是我们又不想修改已经测试完成的代码,那么如何让这个接口能适应我们的软件环境,这里我们需要使用适配器模式,我们现在可以知道如下的内容:
a.目标接口(ITarge):
 public interface ITarget
    
{
        
void CalculateSalary();
    }
b.被适配的对象(Adaptee):
 public abstract  class  CaculateAdaptee
    
{
        
public abstract void CalSalary();
    }

    
public  class EngineerCal : CaculateAdaptee
    
{
        
public override void CalSalary()
        
{
            
        }


    }

    
public  class CleanerCal : CaculateAdaptee
    
{
        
public override void CalSalary()
        
{
            
        }

    }

    
public class HRCal : CaculateAdaptee
    
{
        
public override void CalSalary()
        
{
            
        }

    }
那么他们之间无疑缺少一个适配器(Adapter),来协调彼此,这个适配器的工作就是要使用现有的Adaptee,通过功能的组合等等工作来实现ITarget接口的方法,那么这里有个问题,我们的Adapter类如何使用Adaptee的功能,我们很容易会想到两种方案:
a.Adapter类继承Adaptee类,这样Adatee的方法自然被继承下来(类的Adapter模式)
b.在Adapter类里放一个adaptee一个字段,这样我们也可以实现要求(对象的Adapter模式)
权衡这两个,我们知道有个原则:优先使用对象组合代替继承,原因是继承带来了高的耦合度,父类的变化都会直接影响其子类;而对象的组合则是松的耦合,我们在Adapter放的可以是一个父类对象,可以用其子类来实例化这个对象。
自然而然,我们的适配器模式也就有了这两种实现方式,下面是这两种方式的结构图:
1.类的Adapter模式结构图:

2.对象的Adapter模式结构图:

下面我们分别给出这两种方式的代码,其实差别就在Adapter的实现上:
类的Adapter模式:
 public class EngineerAdapter:EngineerCal,ITarget
    
{
        
public void CalculateSalary()
        
{
            
this.CalSalary();
        }

    }

    
public class CleanerAdapter : CleanerCal, ITarget
    
{
        
public void CalculateSalary()
        
{
            
this.CalSalary();
        }

    }

    
public class HRAdapter : HRCal, ITarget
    
{
        
public void CalculateSalary()
        
{
            
this.CalSalary();
        }

    }
对象的Adapter模式:
public  class Adapter2:ITarget
    
{
        CaculateAdaptee adaptee;
        
public Adapter2(CaculateAdaptee adaptee)
        
{
            
this.adaptee = adaptee;
        }

        
public void CalculateSalary()
        
{
            
this.adaptee.CalSalary();
        }

       
    }        
通过代码,我们很容易就能弄清问题;在实际开发过程中,我们大多数的情况下我们选择使用对象的Adapter模式,只有在特定情况下,我们才选择使用类的Adapter
模式