Що таке метод "статичної фабрики"?
Що таке метод "статичної фабрики"?
Відповіді:
Ми уникаємо прямого доступу до підключень до бази даних, оскільки вони вимагають великих ресурсів. Тому ми використовуємо статичний заводський метод, getDbConnection
який створює з'єднання, якщо ми нижче межі. В іншому випадку він намагається забезпечити "запасне" з'єднання, не виходячи з винятку, якщо його немає.
public class DbConnection{
private static final int MAX_CONNS = 100;
private static int totalConnections = 0;
private static Set<DbConnection> availableConnections = new HashSet<DbConnection>();
private DbConnection(){
// ...
totalConnections++;
}
public static DbConnection getDbConnection(){
if(totalConnections < MAX_CONNS){
return new DbConnection();
}else if(availableConnections.size() > 0){
DbConnection dbc = availableConnections.iterator().next();
availableConnections.remove(dbc);
return dbc;
}else {
throw new NoDbConnections();
}
}
public static void returnDbConnection(DbConnection dbc){
availableConnections.add(dbc);
//...
}
}
Статичний шаблон Фабричний метод є спосіб створення об'єкта Encapsulate. Без фабричного методу, ви б просто викликати клас в конструктор безпосередньо: Foo x = new Foo()
. З допомогою цієї моделі, ви б замість того, щоб викликати метод фабрики: Foo x = Foo.create()
. Конструктори позначені приватними, тому їх не можна викликати, за винятком усередині класу, а заводський метод позначено якstatic
так, що його можна викликати, не маючи попередньо об'єкта.
У цього шаблону є кілька переваг. Одне полягає в тому, що фабрика може вибирати з багатьох підкласів (або реалізаторів інтерфейсу) і повертати це. Таким чином, абонент може вказати бажану поведінку за допомогою параметрів, не знаючи або розуміючи потенційно складну ієрархію класів.
Ще однією перевагою є, як відзначили Метью та Джеймс, контроль доступу до обмеженого ресурсу, такого як з'єднання. Це спосіб реалізувати пули об'єктів багаторазового використання - замість того, щоб будувати, використовувати та руйнувати об’єкт, якщо будівництво та знищення є дорогими процесами, може бути більше сенсу побудувати їх один раз та переробити. Фабричний метод може повернути існуючий, невикористаний створений об'єкт, якщо він має, або сконструювати його, якщо кількість об'єктів нижче деякого нижнього порогу, або викинути виняток або повернутиnull
якщо він перевищує верхній поріг.
Відповідно до статті у Вікіпедії, декілька заводських методів також дозволяють різні інтерпретації подібних типів аргументів. Зазвичай конструктор має те саме ім’я, що і клас, що означає, що у вас може бути лише один конструктор із заданою підписом . Фабрики не настільки обмежені, це означає, що ви можете використовувати два різні методи, які приймають однакові типи аргументів:
Coordinate c = Coordinate.createFromCartesian(double x, double y)
і
Coordinate c = Coordinate.createFromPolar(double distance, double angle)
Це також можна використовувати для поліпшення читабельності, як зауважує Расмус.
ПРИМІТКА! « Статичний метод фабрики є НЕ такий же , як фабричний метод шаблону» (с) Effective Java, Джошуа Блох.
Фабричний метод: "Визначте інтерфейс для створення об'єкта, але дозвольте класам, які реалізують інтерфейс, вирішувати, який клас інстанціювати. Фабричний метод дозволяє відкладати екземпляри класу для підкласів" (c) GoF.
"Статичний заводський метод - це просто статичний метод, який повертає екземпляр класу." (c) Ефективна Java, Джошуа Блох. Зазвичай цей метод знаходиться всередині певного класу.
Різниця:
Ключова ідея статичного заводського методу - отримати контроль над створенням об'єкта та делегувати його від конструктора до статичного методу. Рішення об’єкта, який потрібно створити, схоже на «Фабрика абстрактних», прийняту поза методом (у звичайному випадку, але не завжди). Хоча ключовою (!) Ідеєю Factory Method є делегування рішення, який екземпляр класу створити всередині Factory Method. Наприклад, класична реалізація Singleton - це особливий випадок статичного фабричного методу. Приклад часто використовуваних статичних заводських методів:
Читання можна покращити статичними заводськими методами:
Порівняйте
public class Foo{
public Foo(boolean withBar){
//...
}
}
//...
// What exactly does this mean?
Foo foo = new Foo(true);
// You have to lookup the documentation to be sure.
// Even if you remember that the boolean has something to do with a Bar
// you might not remember whether it specified withBar or withoutBar.
до
public class Foo{
public static Foo createWithBar(){
//...
}
public static Foo createWithoutBar(){
//...
}
}
// ...
// This is much easier to read!
Foo foo = Foo.createWithBar();
private Foo(boolean withBar){/*..*/}
public static Foo createWithBar(){return new Foo(true);}
public static Foo createWithoutBar(){return new Foo(false);}
- мають назви, на відміну від конструкторів, які можуть уточнити код.
- не потрібно створювати новий об’єкт при кожному виклику - об’єкти можна кешувати та використовувати повторно, якщо це необхідно.
- може повернути підтип свого типу повернення - зокрема, може повернути об'єкт, клас реалізації якого невідомий абоненту. Це дуже цінна і широко застосовувана функція у багатьох структурах, які використовують інтерфейси як зворотний тип статичних заводських методів.
Це все зводиться до ремонту. Найкращий спосіб зробити це кожен раз, коли ви використовуєтеnew
ключове слово для створення об'єкта, ви з'єднуєте код, який ви пишете для реалізації.
Заводський зразок дозволяє вам відокремити спосіб створення об’єкта від того, що ви робите з об'єктом. Коли ви створюєте всі свої об'єкти за допомогою конструкторів, ви, по суті, жорстко з'єднуєте код, який використовує об'єкт для цієї реалізації. Код, який використовує ваш об’єкт, "залежить від" цього об'єкта. Це може здатися не великою справою на поверхні, але коли об'єкт змінюється (думайте про зміну підпису конструктора або підкласифікацію об'єкта), вам доведеться повертатися назад і перевпорядкувати речі скрізь.
Сьогодні фабрики значною мірою відсторонені на користь використання залежної інжекції, оскільки їм потрібно багато кодового коду, який, як виявляється, трохи важко підтримувати. Інжекція залежностей в основному еквівалентна фабрикам, але дозволяє вказати, як ваші об'єкти декларативно з'єднуються між собою (за допомогою конфігурації чи анотацій).
Якщо конструктор класу приватний, ви не можете створити об’єкт для класу поза ним.
class Test{
int x, y;
private Test(){
.......
.......
}
}
Ми не можемо створити об'єкт для вище класу поза ним. Таким чином, ви не можете отримати доступ до x, y поза межами класу. Тоді в чому користь цього класу?
Ось відповідь: метод ФАБРИКИ .
Додайте нижченаведений метод у вищевказаний клас
public static Test getObject(){
return new Test();
}
Тож тепер ви можете створити об’єкт для цього класу поза його межами. Як і спосіб ...
Test t = Test.getObject();
Отже, статичний метод, який повертає об'єкт класу шляхом виконання його приватного конструктора, називається методом FACTORY
.
Static Factory Method
публічного конструктора?
Я думав, що я додам трохи світла до цієї публікації на те, що я знаю. Ми широко використовували цю техніку в нашому recent android project
. Замість цього creating objects using new operator
ви також можете використовувати static method
для екземпляра класу. Перелік коду:
//instantiating a class using constructor
Vinoth vin = new Vinoth();
//instantiating the class using static method
Class Vinoth{
private Vinoth(){
}
// factory method to instantiate the class
public static Vinoth getInstance(){
if(someCondition)
return new Vinoth();
}
}
Статичні методи підтримують створення умовного об’єкта : Кожен раз, коли ви викликаєте конструктор, об’єкт буде створюватися, але ви можете цього не хотіти. припустимо, ви хочете перевірити якусь умову лише тоді, ви хочете створити новий об'єкт. Ви не створювали б новий екземпляр Vinoth кожен раз, якщо ваша умова не буде задоволена.
Ще один приклад, взятий з Ефективної Java .
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
Цей метод переводить булеве примітивне значення в булеву посилання на об'єкт. Boolean.valueOf(boolean)
Метод показує нам, він ніколи не створює об'єкт. Можливість static factory methods
повернення одного і того ж об'єкта від повторногоinvocations
дозволяє класам підтримувати суворий контроль над тим, які екземпляри існують у будь-який час.
Static factory methods
полягає в тому, що вони, на відміну від constructors
них, можуть повернути object
будь-який subtype
тип повернення. Одне застосування цієї гнучкості полягає в тому, що API може повертати об'єкти, не роблячи їхні класи загальнодоступними. Приховування класів впровадження таким чином призводить до дуже компактного API.
Calendar.getInstance () є відмінним прикладом вищесказаного, він створює в залежності від локалі а BuddhistCalendar
, JapaneseImperialCalendar
або за замовчуванням один Georgian
.
Ще один приклад, про який я міг би подумати, - це те Singleton pattern
, коли ти змушуєш своїх конструкторів приватно створювати власний getInstance
метод, де ти впевнений, що завжди є лише один екземпляр.
public class Singleton{
//initailzed during class loading
private static final Singleton INSTANCE = new Singleton();
//to prevent creating another instance of Singleton
private Singleton(){}
public static Singleton getSingleton(){
return INSTANCE;
}
}
Фабричний метод - метод, який дозволяє абстрагувати інстанціювання об'єкта. Як правило, фабрики корисні, коли ви знаєте, що вам потрібен новий примірник класу, який реалізує деякий інтерфейс, але ви не знаєте клас реалізації.
Це корисно при роботі з ієрархіями пов'язаних класів, хорошим прикладом цього може бути набір інструментів GUI. Ви можете просто викликати жорсткі коди до конструкторів для конкретних реалізацій кожного віджета, але якщо ви коли-небудь хотіли поміняти один інструментарій на інший, у вас було б багато місць змінити. Використовуючи фабрику, ви зменшите кількість коду, який вам потрібно буде змінити.
Однією з переваг, що випливає з фабрики Static, є те, що API може повертати об'єкти, не роблячи їх класи загальнодоступними. Це призводить до дуже компактного API. У Java це досягається класом Collections, який приховує близько 32 класів, що робить API колекції дуже компактним.
Статичний заводський метод хороший, коли ви хочете переконатися, що лише один окремий екземпляр поверне клас бетону, який буде використаний.
Наприклад, у класі підключення до бази даних, можливо, ви хочете, щоб лише один клас створив підключення до бази даних, так що якщо ви вирішите перейти з Mysql на Oracle, ви можете просто змінити логіку в одному класі, а решта програми буде використовувати нове з'єднання.
Якщо ви хочете реалізувати об'єднання баз даних, це також можна зробити, не впливаючи на решту програми.
Це захищає решту програми від змін, які ви можете внести на завод, що і є метою.
Причиною статичності є те, що якщо ви хочете відслідковувати деякий обмежений ресурс (кількість підключень сокет або ручки файлів), то цей клас може відслідковувати кількість переданих та повернутих, щоб не вичерпати обмежений ресурс.
Однією з переваг статичних заводських методів з приватним конструктором (створення об'єкта повинно бути обмежено для зовнішніх класів, щоб забезпечити, щоб екземпляри не створювалися зовні) - це те, що ви можете створювати класи, керовані екземплярами . І керовані екземплярами класи гарантують, що не існує двох рівних відмінних екземплярів ( a.equals (b), якщо і лише якщо a == b ) під час роботи вашої програми, це означає, що ви можете перевірити рівність об'єктів з оператором == замість методу рівних , згідно з Ефективним Java.
Здатність статичних заводських методів повертати один і той же об'єкт із повторних викликів дозволяє класам підтримувати суворий контроль над тим, які екземпляри існують у будь-який час. Кажуть, що класи, які роблять це, контролюються примірниками. Є кілька причин писати класи, керовані екземплярами. Контроль екземплярів дозволяє класу гарантувати, що він є однотонним (п. 3) або невмирущим (п. 4). Крім того, це дозволяє непорушному класу (пункт 15) гарантувати відсутність двох рівних екземплярів: a.equals (b), якщо і лише якщо a == b. Якщо клас дає цю гарантію, то його клієнти можуть використовувати оператор == замість методу рівних (Об'єкт), що може призвести до підвищення продуктивності. Види Enum (пункт 30) дають цю гарантію.
Від ефективної Java, Джошуа Блох (Пункт 1, сторінка 6)
статичний
Член оголосив ключовим словом "статичний".
заводські методи
Методи, що створюють та повертають нові об’єкти.
на Java
Мова програмування відповідає значенню "статичний", але не для визначення "заводської".
Реалізація Java містить класи утиліти java.util.Arrays та java.util.Collections, обидва вони містять статичні заводські методи , приклади цього та способи використання:
Arrays.asList("1","2","3")
Collections.synchronizedList(..), Collections.emptyList(), Collections.unmodifiableList(...)
(Лише деякі приклади можуть перевірити javadocs на приклади методів mor https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html )
Також клас java.lang.String має такі статичні заводські методи :
String.format(...), String.valueOf(..), String.copyValueOf(...)