适配器模式介绍
将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
- Target 目标(ChemicalCompound)
定义了Client使用的特定于域的接口。
- Adapter 适配器(复合)
将接口Adaptee适配到Target接口。
Adaptee (ChemicalDatabank)
定义了一个需要适配的现有接口。
- Client 客户机(AdapterApp)
与符合Target接口的对象协作。
适配器模式
using UnityEngine;
using System.Collections;
public class AdapterStructure : MonoBehaviour
{
void Start( )
{
// Create adapter and place a request
Target target = new Adapter();
target.Request();
}
}
/// <summary>
/// The 'Target' class
/// </summary>
class Target
{
public virtual void Request()
{
Debug.Log("Called Target Request()");
}
}
/// <summary>
/// The 'Adapter' class
/// </summary>
class Adapter : Target
{
private Adaptee _adaptee = new Adaptee();
public override void Request()
{
// Possibly do some other work
// and then call SpecificRequest
_adaptee.SpecificRequest();
}
}
/// <summary>
/// The 'Adaptee' class
/// </summary>
class Adaptee
{
public void SpecificRequest()
{
Debug.Log("Called SpecificRequest()");
}
}
适配器模式案例1
using UnityEngine;
using System.Collections;
//Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.
//This real-world code demonstrates the use of a legacy chemical databank. Chemical compound objects access the databank through an Adapter interface.
namespace AdapterPatternExample1
{
public class AdapterPatternExample1 : MonoBehaviour
{
void Start()
{
// Non-adapted chemical compound
Compound unknown = new Compound("Unknown");
unknown.Display();
// Adapted chemical compounds
Compound water = new RichCompound("Water");
water.Display();
Compound benzene = new RichCompound("Benzene");
benzene.Display();
Compound ethanol = new RichCompound("Ethanol");
ethanol.Display();
}
}
/// <summary>
/// The 'Target' class
/// </summary>
class Compound
{
protected string _chemical;
protected float _boilingPoint;
protected float _meltingPoint;
protected double _molecularWeight;
protected string _molecularFormula;
// Constructor
public Compound(string chemical)
{
this._chemical = chemical;
}
public virtual void Display()
{
Debug.Log("\nCompound: " + _chemical + "------");
}
}
/// <summary>
/// The 'Adapter' class
/// </summary>
class RichCompound : Compound
{
private ChemicalDatabank _bank;
// Constructor
public RichCompound(string name)
: base(name)
{
}
public override void Display()
{
// The Adaptee
_bank = new ChemicalDatabank();
_boilingPoint = _bank.GetCriticalPoint(_chemical, "B");
_meltingPoint = _bank.GetCriticalPoint(_chemical, "M");
_molecularWeight = _bank.GetMolecularWeight(_chemical);
_molecularFormula = _bank.GetMolecularStructure(_chemical);
base.Display();
Debug.Log(" Formula: " + _molecularFormula);
Debug.Log(" Weight : " + _molecularWeight);
Debug.Log(" Melting Pt: " + _meltingPoint);
Debug.Log(" Boiling Pt: " + _boilingPoint);
}
}
/// <summary>
/// The 'Adaptee' class
/// </summary>
class ChemicalDatabank
{
// The databank 'legacy API'
public float GetCriticalPoint(string compound, string point)
{
// Melting Point
if (point == "M")
{
switch (compound.ToLower())
{
case "water": return 0.0f;
case "benzene": return 5.5f;
case "ethanol": return -114.1f;
default: return 0f;
}
}
// Boiling Point
else
{
switch (compound.ToLower())
{
case "water": return 100.0f;
case "benzene": return 80.1f;
case "ethanol": return 78.3f;
default: return 0f;
}
}
}
public string GetMolecularStructure(string compound)
{
switch (compound.ToLower())
{
case "water": return "H20";
case "benzene": return "C6H6";
case "ethanol": return "C2H5OH";
default: return "";
}
}
public double GetMolecularWeight(string compound)
{
switch (compound.ToLower())
{
case "water": return 18.015;
case "benzene": return 78.1134;
case "ethanol": return 46.0688;
default: return 0d;
}
}
}
}
适配器模式案例2
using UnityEngine;
using System.Collections;
namespace AdapterPatternExample2
{
public class AdapterPatternExample2 : MonoBehaviour
{
void Start()
{
IEnemyAttacker tank = new EnemyTank();
EnemyRobot fredTheRobot = new EnemyRobot();
IEnemyAttacker adapter = new EnemyRobotAdaper(fredTheRobot);
fredTheRobot.ReactToHuman("Hans");
fredTheRobot.WalkForward();
tank.AssignDriver("Frank");
tank.DriveForward();
tank.FireWeapon();
adapter.AssignDriver("Mark");
adapter.DriveForward();
adapter.FireWeapon();
}
}
public interface IEnemyAttacker
{
void FireWeapon();
void DriveForward();
void AssignDriver(string driver);
}
public class EnemyTank : IEnemyAttacker
{
public void FireWeapon()
{
int attackDamage = Random.Range(1, 10);
Debug.Log("Enemy Tank does " + attackDamage + " damage");
}
public void DriveForward()
{
int movement = Random.Range(1, 5);
Debug.Log("Enemy Tank moves " + movement + " spaces");
}
public void AssignDriver(string driver)
{
Debug.Log(driver + " is driving the tank");
}
}
// Adaptee:
public class EnemyRobot
{
public void SmashWithHands()
{
int attackDamage = Random.Range(1, 10);
Debug.Log("Robot causes " + attackDamage + " damage with it hands");
}
public void WalkForward()
{
int movement = Random.Range(1, 3);
Debug.Log("Robot walks " + movement + " spaces");
}
public void ReactToHuman(string driverName)
{
Debug.Log("Robot tramps on " + driverName);
}
}
public class EnemyRobotAdaper : IEnemyAttacker
{
EnemyRobot robot;
public EnemyRobotAdaper(EnemyRobot robot)
{
this.robot = robot;
}
public void FireWeapon()
{
robot.SmashWithHands();
}
public void DriveForward()
{
robot.WalkForward();
}
public void AssignDriver(string driver)
{
robot.ReactToHuman(driver);
}
}
}