русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Регистрация фабрик


Дата добавления: 2015-06-12; просмотров: 817; Нарушение авторских прав


У построения объектов иерархии Pet есть один недостаток: каждый раз, когда в иерархию включается новый тип Pet, вы должны добавить его в LiteralPetCreator.java. В системах с регулярным добавлением новых классов это может создать проблемы. Первое, что приходит в голову, — добавить в каждый класс статический инициализатор, который добавлял бы свой класс в некий список. К сожалению, статические инициализаторы вызываются только при первой загрузке класса, поэтому возникает «порочный круг»: класс отсутствует в списке генератора, поэтому генератор не может создать объект этого класса, соответственно, класс не загрузится и не будет помещен в список. По сути, вы вынуждены создать список вручную (разве что вы напишете утилиту, которая будет анализировать исходный код, а затем создавать и компилировать список). Вероятно, лучшее, что можно сделать, — это разместить список в одном централизованном, очевидном месте. Вероятно, лучшим местом для него будет базовый класс иерархии. В этом разделе мы также внесем другое изменение: создание объекта будет передано самому классу с использованием паттерна «метод-фабрика». Метод-фабрика может вызываться полиморфно и создает объект соответствующего типа. В следующей упрощенной версии методом-фабрикой является метод create() интерфейсаFactory:

//: typeinfo/factory/Factory.java

package typeinfo.factory:

public interface Factory<T> { T create(); }

Обобщенный параметр T позволяет create() возвращать разные типы для разных реализаций Factory. Также при этом используется ковариантность возвращаемых типов. В следующем примере базовый класс Part содержит список объектов-фабрик. Фабрики типов, которые должны создаваться методом createRandom(), «регистрируются» в базовом классе включением в список partFactories:

package typeinfo;

import typeinfo.factory.*;



import java.util.*;

 

class Part {

 

@Override

public String toString() {return getClass().getSimpleName(); }

 

static List<Factory<? extends Part>>partFactories

= new ArrayList<Factory<? extends Part>>();

 

static {

// При вызове Collections addAll() выдается предупреждение

// "unchecked generic array creation for varargs parameter"

partFactories.add(new FuelFilter.Factory());

partFactories.add(new AirFilter.Factory());

partFactories.add(new CabinAirFilter.Factory());

partFactories.add(new OilFilter.Factory());

partFactories.add(new FanBelt.Factory());

partFactories.add(new PowerSteeringBelt.Factory());

partFactories.add(new GeneratorBelt.Factory());

}

private static Random rand = new Random(47);

public static Part createRandom() {

int n = rand.nextInt(partFactories.size());

return partFactories.get(n).create();

}

}

class Filter extends Part {}

 

class FuelFilter extends Filter {

// Создание фабрики для каждого конкретного типа

public static class Factory implements typeinfo.factory.Factory<FuelFilter> {

@Override

public FuelFilter create() { return new FuelFilter ();}

}

}

 

class AirFilter extends Filter {

public static class Factory implements typeinfo.factory.Factory<AirFilter> {

@Override

public AirFilter create() { return new AirFilter(); }

}

}

 

class CabinAirFilter extends Filter {

public static class Factory implements typeinfo.factory.Factory<CabinAirFilter> {

@Override

public CabinAirFilter create() {return new CabinAirFilter();}

}

}

 

class OilFilter extends Filter {

public static class Factory implements typeinfo.factory.Factory<OilFilter> {

@Override

public OilFilter create() { return new OilFilter(); }

}

}

 

class Belt extends Part {}

 

class FanBelt extends Belt {

public static class Factory implements typeinfo.factory.Factory<FanBelt> {

@Override

public FanBelt create() { return new FanBelt(); }

}

}

 

class GeneratorBelt extends Belt {

public static class Factory implements typeinfo.factory.Factory<GeneratorBelt> {

@Override

public GeneratorBelt create() {return new GeneratorBelt();}

}

}

 

class PowerSteeringBelt extends Belt {

public static class Factory implements typeinfo.factory.Factory<PowerSteeringBelt> {

@Override

public PowerSteeringBelt create() {return new PowerSteeringBelt();}

}

}

 

public class RegisteredFactories {

 

public static void main(String[] args) {

for(int i = 0; i < 10; i++)

System.out.println(Part.createRandom());

}

}

<spoiler text="Output:">

GeneratorBelt CabinAirFilter GeneratorBelt AirFilter PowerSteeringBelt CabinAirFilter Fuel

Filter PowerSteeringBelt PowerSteeringBelt Fuel Filter

</spoiler> He все классы иерархии рассчитаны на создание экземпляров; в нашем примере классы Filter и Belt существуют исключительно в целях классификации. Экземпляры этих классов не создаются — только одного из их субклассов. Если класс должен создаваться посредством createRandom(), он содержит внутренний класс Factory. Хотя для включения всех фабрик в список можно воспользоваться вызовом Collections.addAll(), компилятор выдает предупреждение, поэтому я вернулся к вызовам add(). Метод createRandom()случайным образом выбирает объект фабрики из partFactories и вызывает его метод create() для получения нового объекта Part.



<== предыдущая лекция | следующая лекция ==>
Рекурсивный подсчет | Instanceof и сравнение Class


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.337 сек.