الگوی Factory Method

الگوی Factory Method(متد کارخانه) در دسته الگوهای ایجادی قرار دارد. تعریف یک واسط برای ایجاد یک شی، اما به زیر کلاس ها اجازه میدهد تصمیم بگیرند که کدام کلاس نمونه سازی شود. Factory Method به کلاس اجازه می دهد نمونه اولیه را به زیر کلاس ها منتقل کند. به عبارت دیگر متمرکز سازی نمونه سازی از کلاس های مشابه و کاهش اتصال مستقیم به محصول .UML class diagram شركت كنندگان کلاس ها و اشیاء شرکت کننده در این الگو عبارتند از:محصول Product (درمثال دنیای واقعی Page) : واسط(interface) اشیا را تعریف می کند که Factory Method ایجاد می کند.(واسط کلی محصول ها Products)محصول سفت ConcreteProduct ( صفحه مهارت ها ، صفحه تجربیات ، صفحه آموزش SkillsPage, Educati, ExperiencePage) :واسط محصول(Product) را پیاده سازی می کند.سازنده Creator (درمثال دنیای واقعی اسناد Document):متد کارخانه-Factory Method اعلام میکند، که یک شی از نوع محصول را باز می گرداند.همچنین ممکن است Creator یک پیاده سازی پیش فرض از Factory Method که شی پیش فرض ConcreteProduct را برمیگرداند تعریف کند. به ممکن است Factory Method را برای ایجاد یک شیء محصول فراخوانی کند.به عبارت دیگر کلاسی که Factory Method را فراهم کرده است.متدکارخانه Factory Method(): متد سازنده‌ای که -بر اساس درخواست یا شرایط- تصمیم گیری می کند از چه زیر کلاسی باید نمونه سازی کند و شی ایجاد شده را برگرداند. سازنده سفت ConcreteCreator (گزارش، رزومه Report, Resume) :متد کارخانه-Factory Method را برای بازگرداندن نمونه ای از یک محصول بتن (ConcreteProduct) لغو (overrides)می کند.ساختار کلی کد ساختاری کد روش کارخانه را ارائه می دهد که انعطاف پذیری زیادی در ایجاد اشیاء مختلف دارد.کلاس Abstract می تواند یک شیء پیش فرض را فراهم کند، اما هر زیر کلاس می تواند یک نسخه گسترده ای از شی را ایجاد کند. using System; namespace DoFactory.GangOfFour.Factory.Structural { /// <summary> /// MainApp startup class for Structural /// Factory Method Design Pattern. /// </summary> class MainApp { /// <summary> /// Entry point into console application. /// </summary> static void Main() { // An array of creators Creator[] creators = new Creator[2]; creators[0] = new ConcreteCreatorA(); creators[1] = new ConcreteCreatorB(); // Iterate over creators and create products foreach (Creator creator in creators) { Product product = creator.FactoryMethod(); Console.WriteLine("Created {0}", product.GetType().Name); } // Wait for user Console.ReadKey(); } } /// <summary> /// The 'Product' abstract class /// </summary> abstract class Product { } /// <summary> /// A 'ConcreteProduct' class /// </summary> class ConcreteProductA : Product { } /// <summary> /// A 'ConcreteProduct' class /// </summary> class ConcreteProductB : Product { } /// <summary> /// The 'Creator' abstract class /// </summary> abstract class Creator { public abstract Product FactoryMethod(); } /// <summary> /// A 'ConcreteCreator' class /// </summary> class ConcreteCreatorA : Creator { public override Product FactoryMethod() { return new ConcreteProductA(); } } /// <summary> /// A 'ConcreteCreator' class /// </summary> class ConcreteCreatorB : Creator { public override Product FactoryMethod() { return new ConcreteProductB(); } } } OutputCreated ConcreteProductACreated ConcreteProductBیاpublic abstract class Product { public abstract void Show(); } public class DefaultProduct: Product { public override void Show() { Console.WriteLine("I'm DefaultProduct"); } } public class ConcreteProductA: Product { public override void Show() { Console.WriteLine("I'm ConcreteProductA"); } } public class ConcreteProductB: Product { public override void Show() { Console.WriteLine("I'm ConcreteProductB"); } } public abstract class Creator { public abstract Product FactoryMethod(int a); } public class ConcreteCreator: Creator { public override Product FactoryMethod(int a) { if (a < 0) return new ConcreteProductA(); else if (a > 0) return new ConcreteProductB(); else return new DefaultProduct(); } } public class Test { public static void Main() { var creator = new ConcreteCreator(); Product p; p = creator.FactoryMethod(-1); p.Show(); p = creator.FactoryMethod(1); p.Show(); p = creator.FactoryMethod(0); p.Show(); Console.ReadKey(); } } /* OutputI'm ConcreteProductAI'm ConcreteProductBI'm DefaultProduct*/کد در دنیای واقعیروش کارخانه ارائه انعطاف پذیری در ایجاد اسناد مختلف را نشان می دهد.کلاس های مستند مشتق شده گزارش و رزومه نسخه های گسترده ای از کلاس Document را ایجاد می کنند.در اینجا ، Factory Method در سازنده (constructor) کلاس پایه (base class) اسناد(Document) فراخوانی شده است. using System; using System.Collections.Generic; namespace DoFactory.GangOfFour.Factory.RealWorld { /// <summary> /// MainApp startup class for Real-World /// Factory Method Design Pattern. /// </summary> class MainApp { /// <summary> /// Entry point into console application. /// </summary> static void Main () { // Note: constructors call Factory Method Document[] documents = new Document[2]; documents[0] = new Resume (); documents[1] = new Report (); // Display document pages foreach (Document document in documents) { Console.WriteLine ("\n" + document.GetType ().Name + "--"); foreach (Page page in document.Pages) { Console.WriteLine (" " + page.GetType ().Name); } } // Wait for user Console.ReadKey (); } } /// <summary> /// The 'Product' abstract class /// </summary> abstract class Page { } /// <summary> /// A 'ConcreteProduct' class /// </summary> class SkillsPage : Page { } /// <summary> /// A 'ConcreteProduct' class /// </summary> class Educati : Page { } /// <summary> /// A 'ConcreteProduct' class /// </summary> class ExperiencePage : Page { } /// <summary> /// A 'ConcreteProduct' class /// </summary> class Introducti : Page { } /// <summary> /// A 'ConcreteProduct' class /// </summary> class ResultsPage : Page { } /// <summary> /// A 'ConcreteProduct' class /// </summary> class Conclusi : Page { } /// <summary> /// A 'ConcreteProduct' class /// </summary> class SummaryPage : Page { } /// <summary> /// A 'ConcreteProduct' class /// </summary> class BibliographyPage : Page { } /// <summary> /// The 'Creator' abstract class /// </summary> abstract class Document { private List<Page> _pages = new List<Page> (); // Constructor calls abstract Factory method public Document () { this.CreatePages (); } public List<Page> Pages { get { return _pages; } } // Factory Method public abstract void CreatePages (); } /// <summary> /// A 'ConcreteCreator' class /// </summary> class Resume : Document { // Factory Method implementation public override void CreatePages () { Pages.Add (new SkillsPage ()); Pages.Add (new Educati ()); Pages.Add (new ExperiencePage ()); } } /// <summary> /// A 'ConcreteCreator' class /// </summary> class Report : Document { // Factory Method implementation public override void CreatePages () { Pages.Add (new Introducti ()); Pages.Add (new ResultsPage ()); Pages.Add (new Conclusi ()); Pages.Add (new SummaryPage ()); Pages.Add (new BibliographyPage ()); } } } OutputResume ------- SkillsPage Educati ExperiencePageReport ------- Introducti ResultsPage Conclusi SummaryPage BibliographyPageمنبع