вівторок, 9 вересня 2014 р.

Патерн «Фабрика»

Вирізка із книги "GoF Design Patterns - with examples using Java and UML2" by: Benneth Christiansson (Ed.) Mattias Forss, Ivar Hagen, Kent Hansson, Johan Jonasson, Mattias Jonasson, Fredrik Lott, Sara Olsson, and Thomas Rosevall. License: Creative Commons Attribution-ShareAlike 3.0 License.

Визначення
Патерн Фабрика (Factory Pattern) надає шлях використання екземпляру як об’єктну фабрику. Фабрика може повертати екземпляр одного з декількох можливих класів (у ієрархії класів), в залежності від заданих даних.

Де використовується:
  • Коли клас не може передбачити, який об’єкт, якого класу потрібно створити
  • Ви хочете вказати, екземпляр якого клас хочете створити
  • Коли ви маєте класи, які походять від одних і тих же класів, або ж класи, які ділять один інтерфейс.  Тобто, методи у екземплярів цих класів одні і ті ж самі і можуть використовуватися взаємозамінно.  
  • Коли ви хочете ізолювати клієнта від актуального типу, що ініціалізується.
Переваги
  • Клієнту не потрібно знати кожен підклас об’єктів, що необхідно створити. Лише необхідне посилання на абстрактний клас або ж інтерфейс і об’єкт фабрики.
  • Фабрика інкапсулює створення об’єктів. Це може бути корисним, якщо процес створення доволі складний.
Недоліки/наслідки
  • Неможливо змінити реалізовуваний клас без перекомпіляції
Структура

Невеличкий приклад

Даний приклад показує як створити два різних конкретних продукти (Products) використовуючи ProductFactory. ProductA використовує метод суперкласу writeName. ProductB реалізовує writeName, що  перевертає ім’я.

public abstract class Product { 
public void writeName(String name) { 
    System.out.println("My name is "+name); 
    } 
} 
public class ProductA extends Product { } 
public class ProductB extends Product { 
    public void writeName(String name) { 
        StringBuilder tempName = new StringBuilder().append(name); 
        System.out.println("My reversed name is" + 
tempName.reverse()); 
    } 
} 
public class ProductFactory { 
    Product createProduct(String type) { 
        if(type.equals("B")) 
            return new ProductB(); 
  else 
    return new ProductA(); 
    } 
}
public class TestClientFactory { 
    public static void main(String[] args) { 
        ProductFactory pf = new ProductFactory(); 
  Product prod; 
  prod = pf.createProduct("A"); 
  prod.writeName("John Doe"); 
  prod = pf.createProduct("B"); 
  prod.writeName("John Doe"); 
    } 
}
Коли виконати TestClientFactory отримуємо:
c:> My name is John Doe 
c:> My reversed name is eoD nhoJ

Життєвий приклад

Об’єкт Connection у пакеті java sql є фабрикою.  В залежності від драйвера бази даних, ви можете отримати потрібну реалізацію інтерфейсу Statement постачальника бази даних. В наступному прикладі ми отримуємо актуальний об’єкт OracleStatement з пакету oracle.jdbc.driver, коли викликаємо createStatement.

import java.sql.*; 
public class TestClientFactoryUsage { 
    static Connection con; 
    static Statement stmt; 
    
    public static void main(String[] args) { 
        try { 
      Class.forName("oracle.jdbc.driver.OracleDriver"); 
      con = DriverManager.getConnection("myServer", "user", 
                  "password"); 
stmt = con.createStatement(); 
   } catch(Exception e) {} 
    } 
}  

Переклад Volodimirg (Volodimirg@ukr.net)