بایگانی

نوشته های برچسب زده شده ‘الگوی Template method’

الگوی Template method

۱۴ فروردین ۱۳۸۶ ۳ دیدگاه

 

بعضی ار مردم نمی توانند زندگی را بدون قهوه تصور کنند و بعضی دیگر زندگی را بدون چای نمی توانند تصور کنند. ولی جزء تشکیل دهنده اصلی هر دو کافئین است. شباهت های دیگر نیز بین این دو مورد وجود دارد. روش ساخت هر دوی آنها تقریبا مشابه است. شما اغلب موارد به ترتیب زیر عمل می کنید.

دستوالعمل ساخت قهوه:

۱٫       مقداری آب را می جوشانید.

۲٫       مقدار قهوه در آب جوشانده شده می ریزد تا دم بکشد.

۳٫       فهوه را در فنجان می ریزد.

۴٫       مقداری شکر و یا شیر به آن اضافه می کنید.

دستورالعمل ساخت چای:

۱٫       مقداری آب را می جوشانید.

۲٫       مقدار چای خشک در آب جوشانده شده می ریزد تا دم بکشد.

۳٫       چای را در فنجان می ریزد.

 

۴٫       مقداری شکر به آن اضافه می کنید.

 

 

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

 

کلاس قهوه

Public Class Coffee

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

    Public Sub prepareRecipe()

        مراحل تهیه قهوه

        boilWater()

        brewCoffeeGrinds()

        pourInCup()

        addSugereAndMilk()

    End Sub

    Public Sub boilWater()

        Console.WriteLine(جوشاندن آب)

    End Sub

    Public Sub brewCoffeeGrinds()

        Console.WriteLine(ریختن پودر قهوه به داخل آب جوشانده شده)

    End Sub

    Public Sub pourInCup()

        Console.WriteLine(ریختن قهوه به فنجان)

    End Sub

    Public Sub addSugereAndMilk()

        Console.WriteLine(اضافه کردن شیر و شکر)

    End Sub

End Class

 

 

کلاس چای

Public Class Tea

    Public Sub prepareRecipe()

        boilWater()

        brewTea()

        pourInCup()

        addSugere()

    End Sub

    Public Sub boilWater()

        Console.WriteLine(جوشاندن آب)

    End Sub

    Public Sub brewTea()

        Console.WriteLine(ریختن چای به داخل آب جوشانده شده)

    End Sub

    Public Sub pourInCup()

        Console.WriteLine(ریختن چای به فنجان)

    End Sub

    Public Sub addSugere()

        Console.WriteLine(اضافه کردن شکر)

    End Sub

End Class

 

 با مشاهده دو کلاس بالا مشاهده می شود که دو متد boilWater و pourInCup دقیقا مشابه یکدیگر هستند. پس طراحی ما دارای اشتباه هست چون بعضی از کدها تکرار شده اند. پس ما باید طراحی خود را تغییر دهیم. ما می توانیم طراحی خود را به صورت زیر تغییر دهیم. دو متد کاملا مشابه در کلاس پایه پیاده سازی می شود. اما چون متد prepareRecipe در هر کلاس به صورت نتفاوت عمل می کند. این متد در زیر کلاس های مربوطه پیاده سازی می شود.

طراحی بالا یک طراحی خوب است اما نمی شود طراحی را بهتر از این کرد؟   اگر توجه کنیم متوجه می شویم که برای تهیه هر دو مورد الگوریتم یکسانی را به کار می بریم:

۱٫       جوشاندن آبی

۲٫       اضافه کردن چای یا قهوه به آب جوشیده شده

۳٫       ریختن نوشیدنی به دست امده در فنجان

۴٫       اضافه کردن چاشنی مورد نظر به نوشیدنی

پس ما می توانیم با کمی تغییرات متد prepareRecipe را در کلاس پایه پیاده سازی کنیم.

 Public Sub prepareRecipe()

        boilWater()

        brewTea()

        pourInCup()

        addSugere()

 End Sub

 

Public Sub prepareRecipe()

        boilWater()

        brewCoffeeGrinds()

        pourInCup()

        addSugereAndMilk()

End Sub

 

 همانطوریکه می توانید مشاهده کنید کلاس مر بوط به قهوه متدهای به نام brewCoffeeGrinds و addSugereAndMilk را استفاده می کند در حالیکه کلاس مربوط به چای از متد های به نام brewTea و addSugere استفاده می کند. یک راه حل این است که برای هر مرحله غیر مشابه یک نام مشترک در نظر بگیریم. نام متدهای brewTea و brewCoffeeGrinds را به brew تغییر دهیم. و نام متدهای addSugereAndMilk و addSugere را به addCondiments  تغییر می دهیم. پس متد prepareRecipe برای هر دو کلاس به صورت زیر تغییر می کند.

Public Sub prepareRecipe()

        boilWater()

        brew ()

        pourInCup()

        addCondiments()

End Sub

 

 پس حالا می توانیم این متد را بطور کامل به کلاس پایه منتقل کنیم و طراحی را به صورت زیر تغییر دهیم.

حالا ما برای این مسله به یک طراحی ائده ال دست یافتیم. کاری که ما برای حل این مسله انجام دادیم به نام الگوی Template method  شناخته می شود. دلیل نامگذاری این الگو را می توانیم با مشاهده متد prepareRecipe از کلاس پایه درک کنیم. اولین اینکه prepareRecipe یک متد است و دوما به عنوان یک قالب برای الگوریتم به کار می رود. برای نمونه در این مثال شامل الگوریتم تهیه یک نوشیدنی می باشد.

الگوی Template method، مراحل انجام یک الگوریتم را در یک متد در کلاس پایه تعریف می کند و اجازه می دهد زیر کلاس ها یک یا چند مرحله از الگوریتم را پیاده سازی کنند. در واقع اسکلت یک الگوریتم در یک متد تعریف می شود.

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

نمودار UML :

نمودار UML این الگو به صورت بالا است. که در آن کلاس AbstractClass یک کلاس Abstract  است. که الگوی قالب در آن تعریف می شود. و متد primitiveOperation یک متد Abstract  است (یک مرحله از الگوریتم) که در زیر کلاس پیاده سازی خواهد شد. همانطوریکه در مثال بالا مشاهده کردیم می تواند بیش از یک کلاس ConcerteClass وجود داشته باشد. این حالت زمانی رخ می دهد که بعضی از مراحل الگوریتم بتواند در روش های مختلف پیاده سازی شود.