Типичным механизмом создания объектов, реализуемых посредством интерфейсов, является паттерн (шаблон) проектирования "Фабричный метод".
Суть паттерна практически полностью описывается его названием. Когда вам требуется получать какие-то объекты, например пакеты сока, вам совершенно не нужно знать как их делают на фабрике. Вы просто говорите «сделайте мне пакет апельсинового сока», а «фабрика» возвращает вам требуемый пакет. Как? Всё это решает сама фабрика, например «копирует» уже существующий эталон. Основное предназначение «фабрики» в том, чтобы можно было при необходимости изменять процесс «появления» пакета сока, а самому потребителю ничего об этом не нужно было сообщать, чтобы он запрашивал его как и прежде.
Как правило, одна фабрика занимается «производством» только одного рода «продуктов». Не рекомендуется «фабрику соков» создавать с учетом производства автомобильных покрышек. Как и в жизни, паттерн «фабрика» часто создается «одиночкой».
Фабричные методы избавляют проектировщиков от необходимости встраивать в код зависящие от приложения классы.
Ну и чтобы все стало более-менее понятно попрактикуемся…
В первом примере мы будем выпускать сервисы как продукт. И у нас будет фабрика которая выпускает эти продукты. Сервис и фабрика будут описаны как интерфейсы. И так же мы создадим по паре реализаций для сервиса и фабрики сервисов. Пример взят из книги "Философия Java". Правда я его немного изменил, чтобы он стал чуть более понятным на мой взгляд.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package pro.java.factory1; | |
import static pro.java.util.Print.*; | |
// Пример фабричных методов. Делаем фабрику сервисов | |
// это то, что будет выпускать наша фабрика, это продукт | |
interface Service { | |
void method1(); | |
void method2(); | |
} | |
// а это наша фабрика сервисов | |
interface ServiceFactory { | |
Service getService(); // фабричный метод | |
Service getService(String name); // фабричный метод | |
} | |
// это первая имплементация "продукта" сервиса | |
class Implementation1 implements Service { | |
String serviceName; | |
public Implementation1() { | |
serviceName = "NoNaMe1"; | |
} | |
public Implementation1(String name) { | |
serviceName = name; | |
} | |
@Override | |
public void method1() { | |
println("Implementation1 method1"); | |
} | |
@Override | |
public void method2() { | |
println("Implementation1 method2"); | |
} | |
public String getName() { | |
return serviceName; | |
} | |
} | |
// это первая имплементация фабрики | |
class Implementation1Factory implements ServiceFactory { | |
String serviceName; | |
public Implementation1Factory() { | |
serviceName = "NoName1F"; | |
} | |
public Implementation1Factory(String name) { | |
serviceName = name; | |
} | |
// метод возвращающий реальный продукт Service | |
@Override | |
public Service getService() { | |
return new Implementation1(serviceName); | |
} | |
@Override | |
public Service getService(String name) { | |
return new Implementation1(name); | |
} | |
} | |
// это вторая имплементация "продукта" сервиса | |
class Implementation2 implements Service { | |
String serviceName; | |
public Implementation2() { | |
serviceName = "NoNaMe2"; | |
} | |
public Implementation2(String name) { | |
serviceName = name; | |
} | |
@Override | |
public void method1() { | |
println("Implementation2 method1"); | |
} | |
@Override | |
public void method2() { | |
println("Implementation2 method2"); | |
} | |
public String getName() { | |
return serviceName; | |
} | |
} | |
// это вторая имплементация фабрики | |
class Implementation2Factory implements ServiceFactory { | |
String serviceName; | |
public Implementation2Factory() { | |
serviceName = "NoName2F"; | |
} | |
public Implementation2Factory(String name) { | |
serviceName = name; | |
} | |
// метод возвращающий реальный продукт Service | |
@Override | |
public Service getService() { | |
return new Implementation2(serviceName); | |
} | |
@Override | |
public Service getService(String name) { | |
return new Implementation2(name); | |
} | |
} | |
public class Factories { | |
public static void main(String[] args) { | |
// выпускаем наши сервисы с помощью разных фабрик | |
serviceConsumer(new Implementation1Factory("Service1")); | |
println(); | |
serviceConsumer(new Implementation2Factory("Service2")); | |
} | |
static void serviceConsumer(ServiceFactory fact) { | |
Service s = fact.getService(); | |
s.method1(); | |
s.method2(); | |
if (s instanceof Implementation1) { | |
Implementation1 i1 = (Implementation1) s; | |
println(i1.getName()); | |
} | |
if (s instanceof Implementation2) { | |
Implementation2 i2 = (Implementation2) s; | |
println(i2.getName()); | |
} | |
} | |
} |
Вывод у программы следующий:
Все эти строки выводятся статическим методом serviceConsumer(), в который я так же добавил код приведения типов, причем очень интересного приведения, когда интерфейсная ссылка приводится к ссылке на объект класса реализующего этот интерфейс. Это делается в блоках if метода serviceConsumer().
Так же я добавил имя сервиса в код имплементации сервиса, а метод получения этого имени описан в классе, а не в интерфейсе.
И еще один примерчик из той же книги…
В нем создаются имплементации игр шашки и шахматы. Ну как бы шашки и шахматы :) Это же пример…
а где код?
ОтветитьУдалитьВот он
Удалитьhttps://bitbucket.org/n0tb0dy/studyingjava/src/master/00019_Interfaces/src/pro/java/factory1/Factories.java
Здравствуйте.будет продолжение по java?спасибо
ОтветитьУдалитьК сожалению пока совсем нет времени на блог. Но продолжить конечно есть в планах.
УдалитьДа, было бы здорово если бы была инфа о дженериках, коллекшн и основные моменты Java 8
УдалитьНадеюсь как будет поменьше работы продолжу блог. Но пока конца краю не видно.
УдалитьThanks for sharing, nice post! Post really provice useful information!
ОтветитьУдалитьCông ty vận chuyển hàng nước ngoài FadoExpress hàng đầu chuyên vận chuyển, chuyển phát nhanh siêu tốc đi khắp thế giới, nổi bật là dịch vụ gửi hàng đi mỹ, gửi hàng đi nhật và gửi hàng đi pháp và dịch vụ chuyển phát nhanh đi hàn quốc uy tín, giá rẻ