الگوی Adapter

الگوی Adapter در دسته الگوهای ساختاری قرار دارد.تبدیل رابط/واسط یک کلاس به رابط/واسط دیگر مورد انتظار کلاینت. Adapter اجازه می دهد کلاس ها به دلیل واسط/رابط (Interface) های ناسازگار که نمی توانستند با هم کارکنند، با همدیگر کار کنند. به عبارت دیگر فراهم کردن امکان استفاده از کلاسی با واسط ناهمگون در یک برنامه دیگر. UML class diagram شركت كنندگان کلاس ها و اشیاء شرکت کننده در این الگو عبارتند از:هدف Target (ترکیب شیمیایی در مثال دنیای واقعی ChemicalCompound): رابط (interface) خاصی را که کلاینت استفاده می کند تعریف می کند. به عبارت دیگر کلاس مورد نیاز برنامه فعلی( چیزی که Client تمایل دارد ببیند). هماهنگ ساز Adapter (ترکیب در مثال دنیای واقعی Compound) : مطابقت دادنinterface(واسط) Adaptee به interface (واسط) Target. عبارت دیگر کلاسی که واسط Adaptee را به واسط Target وفق می دهد. آداپته Adaptee (بانک داده شیمیایی در مثال دنیای واقعی ChemicalDatabank): یک واسط موجود را که نیاز به تطبیق دارد تعریف می کند.عبارت دیگر کلاس ثالثی که قصد داریم از آن در برنامه فعلی استفاده کنیم( کلاسی که باید وفق داده شود). کلاینت Client (در مثال دنیای واقعی AdapterApp): با اشیاء مطابق با واسط Target همکاری می کند.عبارت دیگر کلاسی که از اشیایی استفاده می کند که واسطه Target را پیاده سازی کرده اند. درخواست Request : عملیاتی که Client نیاز دارد.درخواست خاص SpecificRequest : عملیاتی که Adaptee میتواند انجام بدهد و برای برای برآورده شدن Request باید وفق داده شود.توجه دقت کنید پس از نوشتن Adapter ،برنامه به جای Target باید از Adapter استفاده کرده و از این کلاس نمونه سازی کند. ساختار کلی کداین کد ساختاری الگوی آداپتور را نشان می دهد که واسط یک کلاس را بر روی دیگری نشان می دهد تا بتواند با هم کار کند. این کلاس های ناسازگار ممکن است از library ها یا framework های مختلفی باشد. using System; namespace DoFactory.GangOfFour.Adapter.Structural { /// <summary> /// MainApp startup class for Structural /// Adapter Design Pattern. /// </summary> class MainApp { /// <summary> /// Entry point into console application. /// </summary> static void Main () { // Create adapter and place a request Target target = new Adapter (); target.Request (); // Wait for user Console.ReadKey (); } } /// <summary> /// The 'Target' class /// </summary> class Target { public virtual void Request () { Console.WriteLine ("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 () { Console.WriteLine ("Called SpecificRequest()"); } } } OutputCalled SpecificRequest ()یاAdapter Object:public abstract class Target { public abstract void Request(); } public class Adaptee { public void SpecificRequest() { Console.WriteLine("Adaptee.SpecificRequest()"); } } public class Adapter: Target { private Adaptee adaptee = new Adaptee(); public override void Request() { Console.WriteLine("Adapter.Request()"); Console.WriteLine("redirecting the request " + "to the adaptee ..."); adaptee.SpecificRequest(); } } class Test { public static void Main() { Target target = new Adapter(); target.Request(); Console.ReadKey(); } } /* OUTPUT:Adapter.Request()redirecting the request to the adaptee ...Adaptee.SpecificRequest()*/Adapter Class:public interface ITarget { void Request(); } public class Adaptee { public void SpecificRequest() { Console.WriteLine("Adaptee.SpecificRequest()"); } } public class Adapter: Adaptee, ITarget { public virtual void Request() { Console.WriteLine("Adapter.Request()"); Console.WriteLine("redirecting the request " + "to the adaptee ..."); SpecificRequest(); } } class Test { public static void Main() { ITarget target = new Adapter(); target.Request(); Console.ReadKey(); } } /* OUTPUT:Adapter.Request()redirecting the request to the adaptee ...Adaptee.SpecificRequest()*/کد در دنیایی واقعی این کد دنیای واقعی نشان از استفاده از بانک اطلاعاتی شیمی است. اشیاء شیمیایی ترکیب به بانک اطلاعاتی از طریق رابط/واسط آداپتور دسترسی دارند. using System; namespace DoFactory.GangOfFour.Adapter.RealWorld { /// <summary> /// MainApp startup class for Real-World /// Adapter Design Pattern. /// </summary> class MainApp { /// <summary> /// Entry point into console application. /// </summary> static void Main () { // 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 (); // Wait for user Console.ReadKey (); } } /// <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 () { Console.WriteLine ("\nCompound: {0} ------ ", _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 (); Console.WriteLine (" Formula: {0}", _molecularFormula); Console.WriteLine (" Weight : {0}", _molecularWeight); Console.WriteLine (" Melting Pt: {0}", _meltingPoint); Console.WriteLine (" Boiling Pt: {0}", _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; } } } } OutputCompound : Unknown-- -- -- Compound : Water-- -- -- Formula : H20Weight : 18.015Melting Pt : 0Boiling Pt : 100Compound : Benzene-- -- -- Formula : C6H6Weight : 78.1134Melting Pt : 5.5Boiling Pt : 80.1Compound : Alcohol-- -- -- Formula : C2H6O2Weight : 46.0688Melting Pt: -114.1Boiling Pt : 78.3منبع