您的位置:首页 > 其它

设计模式之适配器

2009-08-19 09:38 260 查看
适配器模式用专业术语解释:使一个系统可以使用接口完全不匹配其需求的类?简单的说:在新的系统需要新的接口实现,又要原先系统功能,那怎么办?将两者结合就是adpter模式。

在现实生活中,单一的军刀有一个刀片,一个手柄。可以削苹果,可以宰鹿。当你在宰鹿的时候,发现鹿角需要用锯子。这个时候你就想这把军刀是否可以加个锯子,于是多功能军刀就出来。多功能军刀拥有,一个刀片,一个锯子,等等和 一个手柄。

下面我们来实现它

定义一个食物实体,由 名字和软硬。

/// <summary>
/// 食物接口
/// </summary>
public interface IFood
{
bool IsSoft { get;set;}

string Name { get;set;}

}

/// <summary>
/// 食物
/// </summary>
public class Food : IFood
{
private bool issoft;
private string name;
public Food(string _name, bool _issoft)
{
IsSoft = _issoft;
Name = _name;
}
#region IFood 成员
public bool IsSoft
{
get
{
return issoft;
}
set
{
issoft = value;
}

}
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
#endregion
}


原始只能切肉的军刀 ,只能切软的食物。

/// <summary>
/// 原始军刀
/// </summary>
public class SaberAdptee
{

private bool handle;

/// <summary>
/// 是否使用手柄
/// </summary>
public bool Handle
{
get{
return handle;
}
set{
handle = value;
}
}
public void UseHandle()
{
if(Handle)
{
Console.WriteLine("ready go");
}
else
{
Console.WriteLine("your hand is not knife,please pick up the knife");
}
}

/// <summary>
/// 切割
/// </summary>
/// <param name="food"></param>
public void Butcher(IFood food)
{
if(!Handle)
UseHandle();
if (food.IsSoft)
Console.WriteLine("Saber,s  cutting {0}", food.Name);
else
Console.WriteLine("Saber,s failed cutting,{0} is,not soft",  food.Name);
}
}


锯子接口

public interface ISawTaget
{
void Saw(IFood food);
}


新的多用途军刀,增加个锯子,可以锯硬的食物。

public class MultiSaberAdapter:SaberAdptee,ISawTaget
{
public MultiSaberAdapter()
{
Console.WriteLine("use MultiSaber");
}
#region ISawTaget 成员
public void  Saw(IFood food)
{
if(!Handle)
UseHandle();
if (food.IsSoft)
Console.WriteLine("MultiSaber.s Saw  failed sawwing,{0} is not soft", food.Name);
else
Console.WriteLine("MultiSaber.s Saw  sawwing {0}", food.Name);
}
#endregion
}


class Program
{
static void Main(string[] args)
{
#region Aircraft
//Aircraft ar = new Aircraft();
//ar.TakeOff();

//IAircraft ia = new Seabird();
//ia.TakeOff();

//(ia as Seacraft).IncreaseRevs();

//(ia as Seacraft).IncreaseRevs();

//ia.TakeOff();
//string st = Console.ReadLine();
#endregion

MultiSaberAdapter sa = new MultiSaberAdapter();

IFood deermeat = new Food("deer,s meat",true);
IFood antlers = new Food("deer,s angle", false);

sa.Handle = true;
sa.UseHandle();
sa.Butcher(deermeat);
(sa as SaberAdptee).Butcher(antlers);

(sa as ISawTaget).Saw(antlers);

string a = Console.ReadLine();

}
}


输出结果



在多用途军刀你还可以添加其他的工具,增加新的接口,以上就是经典的适配器模式。它的特点就通过添加新的接口满足客户原先没预料的功能

如果开发者意识系统的部分功能需要与不同的组件实现,而这些组件有可以随时插入,那么系统被适配的机会就增加了。往往客户程序中调用的方法与接口ITaget的名字要一致。而适配器必须能够处理名字的变化。这个时候可插拔适配器概念就产生。

下面还是用军刀的例子说明,我们要处理食物的时候,预先就知道食物有不同的部位要经过不同的处理,有些要切,有些要锯。

现在我们来实现它,

军刀代码

/// <summary>
///
/// 军刀
/// </summary>
public class SaberAdptee
{

private bool handle;

/// <summary>
/// 是否使用手柄
/// </summary>
public bool Handle
{
get{
return handle;
}
set{
handle = value;
}
}
public void UseHandle()
{
if(Handle)
{
Console.WriteLine("ready go");
}
else
{
Console.WriteLine("your hand is not knife,please pick up the knife");
}
}

/// <summary>
/// 切割
/// </summary>
/// <param name="food"></param>
public void Butcher(IFood food)
{
if (!Handle)
{
UseHandle();
Handle = true;
UseHandle();
Butcher(food);
}
else
{
if (food.IsSoft)
Console.WriteLine("Saber,s  cutting {0}", food.Name);
else
Console.WriteLine("Saber,s failed cutting,{0} is,not soft", food.Name);
}
}
}


锯子代码

/// <summary>
/// 锯子
/// </summary>
public class SawAdaptee
{
private bool issoft;

public bool IsSoft
{
get
{
return issoft;
}
set
{
issoft = value;
}

}

public void Saw(string Name)
{
if (IsSoft)
Console.WriteLine("MultiSaber.s Saw  failed sawwing,{0} is not soft", Name);
else
Console.WriteLine("MultiSaber.s Saw  sawwing {0}", Name);

}
}


可插拨适配器代码,它通过一个委托实现。

public class Multi_SaberAdapter
{

public delegate void butchers(IFood ifood);

public butchers butcher;

public Multi_SaberAdapter(SaberAdptee saber)
{

butcher = saber.Butcher;
}

public Multi_SaberAdapter(SawAdaptee saw)
{

butcher = delegate(IFood ifood)
{
saw.IsSoft = ifood.IsSoft;

saw.Saw(ifood.Name);

};

}

}


实现结果

class Program
{
static void Main(string[] args)
{
#region Aircraft
//Aircraft ar = new Aircraft();
//ar.TakeOff();

//IAircraft ia = new Seabird();
//ia.TakeOff();

//(ia as Seacraft).IncreaseRevs();

//(ia as Seacraft).IncreaseRevs();

//ia.TakeOff();
//string st = Console.ReadLine();
#endregion

MultiSaberAdapter sa = new MultiSaberAdapter();

IFood deermeat = new Food("deer,s meat",true);
IFood antlers = new Food("deer,s angle", false);

sa.Butcher(deermeat);
(sa as SaberAdptee).Butcher(antlers);

(sa as ISawTaget).Saw(antlers);

Console.WriteLine();
Console.WriteLine();
Multi_SaberAdapter msad1 = new Multi_SaberAdapter(new SaberAdptee());
msad1.butcher(deermeat);

Multi_SaberAdapter msad2= new Multi_SaberAdapter(new SawAdaptee());

msad2.butcher(antlers);

string a = Console.ReadLine();

}
}


输出结果



可插拨适配器使用场景,系统开发时知道部分功能可能会发生变化,而这些变化不改变原有的部分功能。通过新的适配器统一对外使用,内部拔插各种组件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: