الگوی متد Factory در سی شارپ

پنجشنبه 24 فروردین 1396

در این مقاله ما سعی کردیم مفاهیم پایه و جایگاه استفاده از الگوی متد Factory را پوشش دهیم . فایل ضمیمه مقاله شامل یک پیاده سازی از توسعه نرم افزار در دنیای واقعی با این الگوی طراحی می باشد .

الگوی متد Factory در سی شارپ

معرفی

الگو های طراحی (Design patterns) راه حل های قابل استفاده مجددی هستند ، برای مسائل مشترک طراحی نرم افزار که در دنیای واقعی توسعه نرم افزار وجود دارند.
گروه چهار(Gang of Four)، 23 الگو را به عنوان زیربنای تمامی الگو ها در نظر گرفته اند. این الگو ها به طور کلی در سه گروه دسته بندی می شوند.
⦁    تکوینی (Creational)
⦁     ساختاری (Structural)
⦁     رفتاری (Behavioral)
از دیدگاه گروه چهار الگوی متد Factory درزیر مجموعه الگوی تکوینی قرار دارد.

پیش زمینه:

قبل از یادگیری الگوی متد Factory ماقصد داریم توضیحات مختصری درباره گروه چهار و الگویی که الگوی متد Factory را شامل می شود بدهیم.

گروه چهار چه کسانی هستند؟

گروه چهار نویسندگان کتاب "الگوهای طراحی: عناصر قابل استفاده مجدد در نرم افزار های شئ گرا"
("Design Patterns: Elements of Reusable Object-Oriented Software") هستند.
اهمیت این کتاب در آن است که توصیفی از تکنولوژی های مختلف توسعه و مشکلات آنها ارائه می دهد. افزون بر آن 23 الگوی طراحی در برنامه نویسی شئ گرا را فراهم آورده است.
این چهار نویسنده عبارتند از :
⦁    Erich Gamma
⦁    Richard Helm
⦁    Ralph Johnson
⦁    John Vlissides

حال به به بررسی الگوی متد Factory می پردازیم:

الگوی متد Factory واسطی(interface) برای ساخت یک شی ایجاد می کند.اما کلاسی که این واسط را پیاده سازی می کند تصمیم میگیرد که کدام کلاس نمونه سازی شود. الگوی متد Factory به یک کلاس اجازه میدهد نمونه سازی را به عهده کلاس مشتق شده بگذارد.(برای مثال در پروژه ضمیمه کلاس CardFactory   هیچ نمونه ای تولید نمی کند و تولید نمونه را به عهده کلاس های MoneyBackFactoryوTitaniumFactory وPlatinumFactory می گذارد. در نتیجه اگر شئی از کلاس CreditCard  بخواهیم ابتدا از کلاس CardFactory نمونه ایجاد می کنیم که با نمونه ساز های یکی از سه نوع کارت بالا پر خواهد شد و درنهایت متد GetCreditCardاز کلاس CardFactory  یک نمونه از کلاس CreditCard تحویل خواهد داد.)
الگوی متد Factory برای جایگزینی سازنده کلاس و انتزاعی سازی فرایند تولید شئ استفاده می شود درواقع نوع داده شئ در زمان اجرا معین میگردد.
در این مقاله ما قصد داریم مفاهیم اساسی الگوی متد Factory و راه های پیاده سازی آن را پوشش دهیم.

درکجا از این الگو استفاده کنیم؟

این که کاربر دقیقا مشخص کند که کدام کلاس باید نمونه سازی شود کار بسیار خسته کننده ای است .از این رو برای حل این مشکل می توانیم از الگوی متد Factory استفاده کنیم که ساخت اشیا را برای کاربر راحت میکند.

نمودار  UMLکلاس

کلاس و اشیائی که در نمودار بالا آمده اند.عبارتند از :

⦁    Product : این کلاس یک اینترفیس از اشیاء ارائه می دهد که متد Factory آنها را ایجاد می کند.
⦁    ConcreteProduct: این کلاس اینترفیس کلاس Product را پیاده سازی می کند. این نوع می تواند یک یا چندین کلاس را شامل شود در مثالی که به صورت فایل ضمیمه همراه این مقاله می باشد . این نوع شامل سه کلاس است.
⦁    Creator: این کلاس یک کلاس انتزاعی (abstract) بوده و متد Factory را اعلام می کند. متد Factory در این کلاس نمونه ای از کلاس Product را بازگشت میدهد.
این می تواند یک پیاده سازی پیش فرض از متد Factory باشد که مقدار پیش فرضی برای ConcreteProduct را بازگشت دهد.(از بین تمام کلاس هایی که مربوط به نوع ConcreteProduct ، نمونه ای از کلاسی که به صورت پیش فرض درنظر گرفته شده است را بازگشت دهد. )
⦁    ConcreteCreator : این کلاس کلاس Creator را پیاده سازی می کند و متد Factory را طوری بازنویسی می کند که یک نمونه از کلاس ConcreteProduct را بازگشت دهد.(به ازای تمام کلاس های نوع ConcreteProduct ، پیاده سازی شده و برای هرکدام متد Factory را بازنویسی می کند.)

حال برای درک بهتر مثالی از دنیای واقعی می آوریم.

فرض کنید شما سه کارت متفاوت دارید که اینجا به عنوان کلاس های
⦁    MoneyBack
⦁    Titanium
⦁    Platinum
در نظر گرفته می شوند.

همه ی کلاس هلای فوق کلاس انتزاعی (abstract) از نوع  CreditCard را پیاده سازی می کنند. شما به نمونه ای از یکی از این کلاس ها نیاز دارید اما نمی دانید از کدام یک زیرا نوع آن به کاربر بستگی دارد. سناریو مطرح شده نمونه عالی از نیاز به الگوی متد Factory است.


کدام به چه شکل است؟

کلاس ها و اشیاء موجود در کلاس دیاگرام بالا به صورت زیر شناخته می شوند.
⦁    Product=> CreditCard
⦁    ConcreteProduct=>MoneyBackCreditCard, TitaniumCreditCard, PlatinumCreditCard
⦁    Creator=>CardFactory
⦁    ConcreteCreator=>MoneyBackCardFactory, TitaniumCardFactory, PlatinumCardFactory


در این بخش کد مربوط به هر کلاس را می توانید ببینید:

⦁    Product

    namespace FactoryMethodDesignPatternInCSharp  
    {  
        /// <summary>  
        /// The 'Product' Abstract Class  
        /// </summary>  
        abstract class CreditCard  
        {  
            public abstract string CardType { get; }  
            public abstract int CreditLimit { get; set; }  
            public abstract int AnnualCharge { get; set; }  
        }     
    }  

⦁    ConcreteProduct

MoneyBackCreditCard

using System;  
  
namespace FactoryMethodDesignPatternInCSharp  
{  
    /// <summary>  
    /// A 'ConcreteProduct' class  
    /// </summary>  
    class MoneyBackCreditCard : CreditCard  
    {  
        private readonly string _cardType;  
        private int _creditLimit;  
        private int _annualCharge;  
  
        public MoneyBackCreditCard(int creditLimit, int annualCharge)  
        {  
            _cardType = "MoneyBack";  
            _creditLimit = creditLimit;  
            _annualCharge = annualCharge;  
        }  
  
        public override string CardType  
        {  
            get { return _cardType; }  
        }  
  
        public override int CreditLimit  
        {  
            get { return _creditLimit; }  
            set { _creditLimit = value; }  
        }  
  
        public override int AnnualCharge  
        {  
            get { return _annualCharge; }  
            set { _annualCharge = value; }  
        }  
    }  
}

TitaniumCreditCard

using System;  
  
namespace FactoryMethodDesignPatternInCSharp  
{  
    /// <summary>  
    /// A 'ConcreteProduct' class  
    /// </summary>  
    class TitaniumCreditCard : CreditCard  
    {  
        private readonly string _cardType;  
        private int _creditLimit;  
        private int _annualCharge;  
  
        public TitaniumCreditCard(int creditLimit, int annualCharge)  
        {  
            _cardType = "Titanium";  
            _creditLimit = creditLimit;  
            _annualCharge = annualCharge;  
        }  
  
        public override string CardType  
        {  
            get { return _cardType; }  
        }  
  
        public override int CreditLimit  
        {  
            get { return _creditLimit; }  
            set { _creditLimit = value; }  
        }  
  
        public override int AnnualCharge  
        {  
            get { return _annualCharge; }  
            set { _annualCharge = value; }  
        }      
    }  
} 

PlatinumCreditCard

    using System;  
      
    namespace FactoryMethodDesignPatternInCSharp  
    {  
        /// <summary>  
        /// A 'ConcreteProduct' class  
        /// </summary>  
        class PlatinumCreditCard : CreditCard  
        {  
            private readonly string _cardType;  
            private int _creditLimit;  
            private int _annualCharge;  
      
            public PlatinumCreditCard(int creditLimit, int annualCharge)  
            {  
                _cardType = "Platinum";  
                _creditLimit = creditLimit;  
                _annualCharge = annualCharge;  
            }  
      
            public override string CardType  
            {  
                get { return _cardType; }  
            }  
      
            public override int CreditLimit  
            {  
                get { return _creditLimit; }  
                set { _creditLimit = value; }  
            }  
      
            public override int AnnualCharge  
            {  
                get { return _annualCharge; }  
                set { _annualCharge = value; }  
            }  
        }  
    }  

⦁    Creator

    namespace FactoryMethodDesignPatternInCSharp  
    {  
        /// <summary>  
        /// The 'Creator' Abstract Class  
        /// </summary>  
        abstract class CardFactory  
        {  
            public abstract CreditCard GetCreditCard();  
        }  
    }  

⦁    ConcreteCreator

MoneyBackFactory

    namespace FactoryMethodDesignPatternInCSharp  
    {  
        /// <summary>  
        /// A 'ConcreteCreator' class  
        /// </summary>  
        class MoneyBackFactory : CardFactory  
        {  
            private int _creditLimit;  
            private int _annualCharge;  
      
            public MoneyBackFactory(int creditLimit, int annualCharge)  
            {  
                _creditLimit = creditLimit;  
                _annualCharge = annualCharge;  
            }  
      
            public override CreditCard GetCreditCard()  
            {  
                return new MoneyBackCreditCard(_creditLimit, _annualCharge);  
            }  
        }  
    }  

TitaniumFactory 

namespace FactoryMethodDesignPatternInCSharp      
{      
    class TitaniumFactory: CardFactory      
    {      
        private int _creditLimit;      
        private int _annualCharge;      
      
        public TitaniumFactory(int creditLimit, int annualCharge)      
        {      
            _creditLimit = creditLimit;      
            _annualCharge = annualCharge;      
        }      
      
        public override CreditCard GetCreditCard()      
        {      
            return new TitaniumCreditCard(_creditLimit, _annualCharge);      
        }      
    }      
}  

PlatinumFactory

namespace FactoryMethodDesignPatternInCSharp      
{      
    class PlatinumFactory: CardFactory      
    {      
        private int _creditLimit;      
        private int _annualCharge;      
      
        public PlatinumFactory(int creditLimit, int annualCharge)      
        {      
            _creditLimit = creditLimit;      
            _annualCharge = annualCharge;      
        }      
      
        public override CreditCard GetCreditCard()      
        {      
            return new PlatinumCreditCard(_creditLimit, _annualCharge);      
        }      
    }      
}  

نمونه ای از الگوی متد Factory :

using System;  
  
namespace FactoryMethodDesignPatternInCSharp  
{  
    /// <summary>  
    /// Factory Pattern Demo  
    /// </summary>    
    public class ClientApplication  
    {  
        static void Main()  
        {  
            CardFactory factory = null;  
            Console.Write("Enter the card type you would like to visit: ");  
            string car = Console.ReadLine();  
  
            switch (car.ToLower())  
            {  
                case "moneyback":  
                    factory = new MoneyBackFactory(50000, 0);  
                    break;  
                case "titanium":  
                    factory = new TitaniumFactory(100000, 500);  
                    break;  
                case "platinum":  
                    factory = new PlatinumFactory(500000, 1000);  
                    break;  
                default:  
                    break;  
            }  
  
            CreditCard creditCard = factory.GetCreditCard();  
            Console.WriteLine("\nYour card details are below : \n");  
            Console.WriteLine("Card Type: {0}\nCredit Limit: {1}\nAnnual Charge: {2}",  
                creditCard.CardType, creditCard.CreditLimit, creditCard.AnnualCharge);  
            Console.ReadKey();  
        }  
    }  
} 

خروجی ها :

در اینجا ورودی های قابل قبول از کاربر را می بینید که درخواست نمونه سازی از کلاسی را دارد .

وارد کردن یک نوع کارت معتبر : (MoneyBack/Titanium/Platinum)

آموزش سی شارپ

فایل های ضمیمه

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان
  • C#.net
  • 5k بازدید
  • 6 تشکر

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید