برای فهم بهتر Factory Method شما نیاز دارید تا درک درستی از دلیل پیدایش این الگوها و همچنین مزایای استفاده از آنها داشته باشید.
شما میتوانید با مراجعه به بخش اول (الگوهای طراحی نرم افزار - Design Patterns)، پیشنیاز این آموزش را مطالعه نمایید.
Factory Method یکی از الگوهای خلاقانه (Creational)، در واقع یکی از پرکاربردترین مدلهای نرم افزاری میباشد که برای ایجاد Object های مختلف از آن استفاده میکنند.
فرض کنید ما یک نرم افزار کودک برای رسم اشیا تولید و در نسخه اول ما فقط با شکل دایره شروع کردیم.
با خوش اقبالی شما ، این نرم افزار مورد اسقبال واقع میشود و تصمیم به گسترش آن میگیرید.
برای این کار نیازمند به افزودن اشکال مختلف مانند مربع و مثلث هستیم. تا کودکان بتوانند شکلهای مختلفی را ترسیم کنند.
چون نرم افزار بر پایه یک کلاس Circle بنا شده است با مشکل مواجه میشویم و برای افزودن کلاس Square باید تغییرات در ساختار نرم افزار ایجاد کنیم.
همین موضوع باعث ایجاد وابستگی و همچنین بهم ریختگی ساختار نرم افزار میشود.
این الگو به شما پیشنهاد میدهد تا به جای ایجاد مستقیم Object ها ، آنها را در داخل یک تابع factory method ایجاد کنید.
در واقع کدی که از این factory method استفاده میکند(کلاینت)، تفاوت بین Object های ایجاد شده را نمیفهمد و فقط از ویژگی مشترک بین آنها استفاده میکند.
این الگو یک Interface به نام Product در اختیار کلاس سازنده (Creator) قرار میدهد و کلاس سازنده توسط آن میتواند Object ایجاد کند.
همچنین به زیر کلاسهایی (SubClasses) که از کلاس سازنده استفاده میکنند، امکان ایجاد تغییر در Object خروجی را میدهد.
Product یک Interface است که Object هایی که توسط کلاس سازنده و زیر کلاس ها ایجاد میشوند. از ویژگی های آن استفاده میکنند و بین همه آن مشترک است.
متدی که در کلاس سازنده، امکان ایجاد Object های مختلف به زیرکلاس ها را میدهد Factory Method نام دارد.
طبق تعریف الگو ما نیاز داریم تا یک Interface به نام Shape برای کلاس سازنده ایجاد کنیم.
interface Shape { public function draw(); }
حالا باید تمام Object هایی که از این ویژگی مشترک استفاده میکنند را ایجاد کنیم.
class Square implements Shape { public function draw() { echo "Square Shape" } }
class Circle implements Shape { public function draw() { echo "Circle Shape" } }
class Rectangle implements Shape { public function draw() { echo "Rectangle Shape" } }
حالا یک کلاس Factory (کلاس سازنده) نیاز داریم.
این کلاس شامل یک تابع factory میباشد تا زیر کلاسی هایی که از آن استفاده میکند، بتوانند Object دلخواه خود را ایجاد کنند.
abstract class ShapeFactory { abstract function getShape(); }
در پایان ما نیاز داریم تا زیر کلاسها را برای ایجاد Object بسازیم.
class CircleFactory extends ShapeFactory { public function getShape() { return new Circle(); } }
class SquareFactory extends ShapeFactory { public function getShape() { return new Square(); } }
class RectangleFactory extends ShapeFactory { public function getShape() { return new Rectangle(); } }
در پایان از ساختاری که ایجاد کردیم در کد خود استفاده میکنیم.
function creator(ShapeFactory $creator){ $factoryMethod = $creator->getShape(); $factoryMethod->draw(); } creator(new RectangleFactory()); // Rectangle Shape creator(new CircleFactory()); // Circle Shape creator(new SquareFactory()); // Square Shape
ممکن است پیچیدگی زیادی در پیاده سازی کد ایجاد شود ، زیرا شما نیاز دارید به ازای هر Object یک زیر کلاس بسازید.
http://dref.ir/factory-method-design-pattern/