在 Adapter模式的两种模式中,有一个很重要的概念就是接口继承和实现继承的区别和
联系。接口继承和实现继承是面向对象领域的两个重要的概念,接口继承指的是通过继承,
子类获得了父类的接口,而实现继承指的是通过继承子类获得了父类的实现(并不统共接
口)。在 C++中的 public继承既是接口继承又是实现继承,因为子类在继承了父类后既可以
对外提供父类中的接口操作,又可以获得父类的接口实现。当然我们可以通过一定的方式和
技术模拟单独的接口继承和实现继承,例如我们可以通过 private 继承获得实现继承的效果
(private 继承后,父类中的接口都变为 private,当然只能是实现继承了。),通过纯抽象基
类模拟接口继承的效果,但是在 C++中 pure virtual function 也可以提供默认实现,因此这是
不纯正的接口继承,但是在 Java 中我们可以 interface 来获得真正的接口继承了。
This real-world code demonstrates the use of a legacy chemical databank. Chemical compound objects access the databank through an Adapter interface.
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 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
|