您的位置:首页 > 其它

设计模式之Adapter适配器设计模式

2006-11-14 23:49 501 查看
意图intent:将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
适用性

你想使用一个已经存在的类,而它的接口不符合你的需求。

你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。

(仅适用于对象Adapter)你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。

Definition
Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.

Participants
The classes and/or objects participating in this pattern are:

Target (ChemicalCompound)

defines the domain-specific interface that Client uses.

Adapter (Compound)

adapts the interface Adaptee to the Target interface.

Adaptee (ChemicalDatabank)

defines an existing interface that needs adapting.

Client (AdapterApp)

collaborates with objects conforming to the Target interface.

Adapter模式有两种实现形式,一种是所谓的Adapter Class,另一种是所谓的Adapter Object。
前一种是通过多重继承来实现的,也即Adapter继承了Adaptee和Target来实现,也即在类Adapter中,通过调用Adaptee中的函数来替换(覆盖)掉Target的实现。另一种是Adapter中有一个成员变量是Adaptee,然后也是通过覆盖掉Target来实现的。现在很多语言都不支持多继承了,所以实际上在c#和java中都只能通过后一种方法来实现了。当然了,后一种继承确实也是比前一种要好,因为前一种设计耦合性太高了。
Sample code in C#
This structural code demonstrates the Adapter pattern which maps the interface of one class onto another so that they can work together. These incompatible classes may come from different libraries or frameworks.
// Adapter pattern -- Structural example
using System;

namespace DoFactory.GangOfFour.Adapter.Structural
{

// Mainapp test application

class MainApp
{
static void Main()
{
// Create adapter and place a request
Target target = new Adapter();
target.Request();

// Wait for user
Console.Read();
}
}

// "Target"

class Target
{
public virtual void Request()
{
Console.WriteLine("Called Target Request()");
}
}

// "Adapter"

class Adapter : Target
{
private Adaptee adaptee = new Adaptee();

public override void Request()
{
// Possibly do some other work
// and then call SpecificRequest
adaptee.SpecificRequest();
}
}

// "Adaptee"

class Adaptee
{
public void SpecificRequest()
{
Console.WriteLine("Called SpecificRequest()");
}
}
}
Output
Called SpecificRequest()
This real-world code demonstrates the use of a legacy chemical databank. Chemical compound objects access the databank through an Adapter interface.
// Adapter pattern -- Real World example
using System;

namespace DoFactory.GangOfFour.Adapter.RealWorld
{

// MainApp test application

class MainApp
{
static void Main()
{
// Non-adapted chemical compound
Compound stuff = new Compound("Unknown");
stuff.Display();

// Adapted chemical compounds
Compound water = new RichCompound("Water");
water.Display();

Compound benzene = new RichCompound("Benzene");
benzene.Display();

Compound alcohol = new RichCompound("Alcohol");
alcohol.Display();

// Wait for user
Console.Read();
}
}

// "Target"

class Compound
{
protected string name;
protected float boilingPoint;
protected float meltingPoint;
protected double molecularWeight;
protected string molecularFormula;

// Constructor
public Compound(string name)
{
this.name = name;
}

public virtual void Display()
{
Console.WriteLine("/nCompound: {0} ------ ", name);
}
}

// "Adapter"

class RichCompound : Compound
{
private ChemicalDatabank bank;

// Constructor
public RichCompound(string name) : base(name)
{
}

public override void Display()
{
// Adaptee
bank = new ChemicalDatabank();
boilingPoint = bank.GetCriticalPoint(name, "B");
meltingPoint = bank.GetCriticalPoint(name, "M");
molecularWeight = bank.GetMolecularWeight(name);
molecularFormula = bank.GetMolecularStructure(name);

base.Display();
Console.WriteLine(" Formula: {0}", molecularFormula);
Console.WriteLine(" Weight : {0}", molecularWeight);
Console.WriteLine(" Melting Pt: {0}", meltingPoint);
Console.WriteLine(" Boiling Pt: {0}", boilingPoint);
}
}

// "Adaptee"

class ChemicalDatabank
{
// The Databank 'legacy API'
public float GetCriticalPoint(string compound, string point)
{
float temperature = 0.0F;

// Melting Point
if (point == "M")
{
switch (compound.ToLower())
{
case "water" : temperature = 0.0F; break;
case "benzene" : temperature = 5.5F; break;
case "alcohol" : temperature = -114.1F; break;
}
}
// Boiling Point
else
{
switch (compound.ToLower())
{
case "water" : temperature = 100.0F; break;
case "benzene" : temperature = 80.1F; break;
case "alcohol" : temperature = 78.3F; break;
}
}
return temperature;
}

public string GetMolecularStructure(string compound)
{
string structure = "";

switch (compound.ToLower())
{
case "water" : structure = "H20"; break;
case "benzene" : structure = "C6H6"; break;
case "alcohol" : structure = "C2H6O2"; break;
}
return structure;
}

public double GetMolecularWeight(string compound)
{
double weight = 0.0;
switch (compound.ToLower())
{
case "water" : weight = 18.015; break;
case "benzene" : weight = 78.1134; break;
case "alcohol" : weight = 46.0688; break;
}
return weight;
}
}
}
Output
Compound: Unknown ------

Compound: Water ------
Formula: H20
Weight : 18.015
Melting Pt: 0
Boiling Pt: 100

Compound: Benzene ------
Formula: C6H6
Weight : 78.1134
Melting Pt: 5.5
Boiling Pt: 80.1

Compound: Alcohol ------
Formula: C2H6O2
Weight : 46.0688
Melting Pt: -114.1
Boiling Pt: 78.3
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: