آشنایی با Abstract Factory Design Pattern در جاوا
در این مقاله قصد داریم تا با Abstract Factory Design Pattern آشنا شویم. این مقاله شباهت بسیاری به مقاله قبل دارد. به این معنا که نیاز است پیش از این مقاله، مقاله قبلی را مطالعه فرمایید.
این Design Pattern در اصل یک Factory است که وظیفه ایجاد دیگر Factory ها را بر عهده دارد. این Design Pattern در دسته ی creational است. همانطور که در مقاله قبل اشاره شد، وظیفه Factory این است که متناسب با نوع ورودی، کلاس مناسب را ایجاد و برگرداند. بنابراین در اینجا با استفاده از Factory در یک سطح بالاتر، این Factory ها را ایجاد میکنیم.
مزایا استفاده از Abstract Factory
وقتی از این Design Pattern استفاده میکنیم، کاربر شیوه instance سازی برای کلاس ها نمیشود. همچنین میتوانیم یک نوع جدید به کلاس ها اضافه کنیم و کاربر تنها با مشخص کردن نوعش، از آن استفاده کند.
معایب استفاده از Abstract Factory
همانطور که اشاره شد این Design Pattern کاربر را از چگونگی و مراحل پیاده سازی کلاس دور میکند. اما گاهی نیاز است تا در Factory ها تغییراتی بوجود آید که ممکن است ساختار اصلی API آن را تغییر دهد. ساختاری که کاربر بر اساس آنها از این API استفاده میکند و ممکن است با مشکل مواجه شود.
پیاده سازی
برای پیاده سازی یک ساختار را تعریف میکنیم و بر اساس آن، کلاس های مورد نظر را در این Design Pattern پیاده سازی میکنیم. فرض کنید دو نوع وسیله نقلیه داریم که شامل خودرو و موتور سیکلت میشود. بنابراین برای هریک از این دسته ها یک interface تعریف میکنیم. برای به این صورت تعریف میکنیم:
package abstractFactory; public interface Car { void getCarInfo(); }
و برای موتور سیکلت به این صورت تعریف میکنیم:
package abstractFactory; public interface Motorcycles { void getMotorInfo(); }
اکنون باید چند کلاس که مدل های وسیله نقلیه هستند، را پیاده سازی کنیم. برای خودرو ها سه مدل را پیاده سازی میکنیم:
public class Toyota implements Car { @Override public void getCarInfo() { System.out.println("Toyota car inf"); } }
public class Renault implements Car { @Override public void getCarInfo() { System.out.println("Renault car info"); } }
public class Peugeot implements Car { @Override public void getCarInfo() { System.out.println("Peugeot car info"); } }
و برای موتور سیکلت ها سه مدل را پیاده سازی میکنیم:
public class Yamaha implements Motorcycle{ @Override public void getMotorInfo() { System.out.println("Yamaha motorcycle info"); } }
public class Suzuki implements Motorcycle { @Override public void getMotorInfo() { System.out.println("Suzuki motorcycles info"); } }
public class Honda implements Motorcycle { @Override public void getMotorInfo() { System.out.println("Honda motorcycle info"); } }
اکنون برای هریک از این interface ها یک کلاس Factory ایجاد میکنیم تا متناسب با ورودی، کلاس مورد نظر را برای ما ایجاد کند. اما پیش از آن یک کلاس در یک سطح بالاتر ایجاد میکنیم تا مشخص کننده نوع ورودی باشد. این کلاس را AbstractFactory مینامیم:
public abstract class AbstractFactory { abstract Car getCar(EnumHelper.Car car); abstract Motorcycle getMotorCycle(EnumHelper.MotorCycle motorCycle); }
این کلاس دریافت کننده ورودی اصلی است که مشخص میکند وسیله نقلیهای که میخواهیم از چه نوعی باشد. اکنون کلاس هایی که باید مدل وسیله نقلیه را برگردانند، از این کلاس ارث بری میکنند و متد های آن را پیاده سازی میکنند. برای خودرو به این صورت مینویسیم:
public class CarFactory extends AbstractFactory { @Override Car getCar(EnumHelper.Car car) { if (car.equals(EnumHelper.Car.PEUGEOT)) { return new Peugeot(); } else if (car.equals(EnumHelper.Car.RENAULT)) { return new Renault(); } else if (car.equals(EnumHelper.Car.TOYOTA)) { return new Toyota(); } return null; } @Override Motorcycle getMotorCycle(EnumHelper.MotorCycle motorCycle) { return null; } }
و برای موتور سیکلت به این صورت مینویسیم:
public class MotorcycleFactory extends AbstractFactory { @Override Car getCar(EnumHelper.Car car) { return null; } @Override Motorcycle getMotorCycle(EnumHelper.MotorCycle motorCycle) { if (motorCycle.equals(EnumHelper.MotorCycle.HONDA)) { return new Honda(); } else if (motorCycle.equals(EnumHelper.MotorCycle.SUZUKI)) { return new Suzuki(); } else if (motorCycle.equals(EnumHelper.MotorCycle.YAMAHA)) { return new Yamaha(); } return null; } }
اکنون نیاز به یک کلاس دیگر داریم تا در نقش سازنده اصلی باشد:
public class FactoryProducer { public static AbstractFactory create(EnumHelper.Vehicle vehicle) { if (vehicle.equals(EnumHelper.Vehicle.CAR)) { return new CarFactory(); } else if (vehicle.equals(EnumHelper.Vehicle.MOTOR_CYCEL)) { return new MotorcycleFactory(); } return null; } }
برای استفاده از این Design Pattern میتوانیم به این صورت عمل کنیم:
public class Client { public static void main(String[] args) { AbstractFactory carAbstractFactory = FactoryProducer.create(EnumHelper.Vehicle.CAR); Car car = carAbstractFactory.getCar(EnumHelper.Car.PEUGEOT); car.getCarInfo(); AbstractFactory motorAbstractFactory = FactoryProducer.create(EnumHelper.Vehicle.MOTOR_CYCEL); Motorcycle motorCycle = motorAbstractFactory.getMotorCycle(EnumHelper.MotorCycle.SUZUKI); motorCycle.getMotorInfo(); } }
با استفاده از این Design Pattern میتوانیم به راحتی به پروژه مدل های گوناگون خودرو و موتور سیکلت و یا نوع های دیگری از وسایل نقلیه را اضافه کنیم و تنها کافی است تا به Enum که برای مشخص کردن نوع و مدل وسیله نقلیه اختصاص دادهایم٬ مورد مورد نظر را اضافه کنیم. به این ترتیب کاربر مصرف کننده کمترین ارتباط را با شیوه ایجاد کلاس ها دارد و میتوانیم پروژه را به راحتی گسترش دهیم.
با ما همراه باشید.
دیدگاهتان را بنویسید
برای نوشتن دیدگاه باید وارد بشوید.