2009-02-24 3 views
0

Я пытался создать фабрику (на Java), которая запрещает подклассификацию фабричного продукта и предотвращает использование конкретных заводов кем-либо, кроме абстрактной фабрики. Что вы думаете об этом ...Factory pattern

class Client 
{ 
    public static void main(String[] args) 
    { 
     Animal animal = Animal.create(Lion.class); 
     animal.doGrowl(); 
     animal = Animal.create(Cow.class); 
     animal.doGrowl(); 
    } 
} 

final class Animal 
{ 
    private Growl growl = null; 

    private Animal() 
    { 
    } 

    public void doGrowl() 
    { 
     growl.exec(); 
    } 

    public abstract class Growl 
    { 
     public abstract void exec(); 

     public final void initialize() 
     { 
      if (growl != null) 
      { 
       throw new IllegalStateException("Already initialized."); 
      } 
      growl = this; 
     } 
    } 

    public abstract static class Factory 
    { 
     public Factory(FactoryInitializer initializer) 
     { 
      initializer.validate(); 
     } 

     public abstract void attachGrowl(Animal a); 
    } 

    public static final class FactoryInitializer 
    { 
     private boolean isValid = true; 

     private FactoryInitializer() 
     { 
     } 

     public void validate() 
     { 
      if (isValid) 
      { 
       isValid = false; 
      } 
      else 
      { 
       throw new IllegalStateException("FactoryInitializer is not valid."); 
      } 
     } 
    } 

    public static Animal create(Class<? extends Factory> factoryClass) 
    { 
     try 
     { 
      Constructor constructor = factoryClass.getConstructor(new Class[]{FactoryInitializer.class}); 
      Factory factory = (Factory) constructor .newInstance(new Object[]{new FactoryInitializer()}); 
      Animal animal = new Animal(); 
      factory.attachGrowl(animal); 
      if (animal.growl == null) 
      { 
       throw new IllegalStateException("Animal factory did not initialize Growl."); 
      } 
      return animal; 
     } 
     catch (Exception e) 
     { 
      return null; 
     } 
    } 
} 

class Lion extends Animal.Factory 
{ 
    public Lion(Animal.FactoryInitializer initializer) 
    { 
     super(initializer); 
    } 

    public void attachGrowl(Animal a) 
    { 
     a.new Growl() 
     { 
      public void exec() 
      { 
       System.out.println("rarrrrrr"); 
      } 
     }.initialize(); 
    } 
} 

class Cow extends Animal.Factory 
{ 
    public Cow(Animal.FactoryInitializer initializer) 
    { 
     super(initializer); 
    } 

    public void attachGrowl(Animal a) 
    { 
     a.new Growl() 
     { 
      public void exec() 
      { 
       System.out.println("mmooooo"); 
      } 
     }.initialize(); 
    } 
} 
+17

Можете ли вы дать английское описание проблемы реального мира, к которой это относится? – TofuBeer

+0

Я спросил об этом некоторое время назад и никогда не объяснял, почему я хотел это знать. В основном я создавал модульный музыкальный синтезатор (например, Music N) и хотел, чтобы пользователи api могли реализовать свои собственные генераторы устройств, которые в основном представляют собой объекты, которые синтезируют или обрабатывают сигнал (массив float) и могут быть соединены вместе. Наверное, я был просто расстроен, никто не видел для этого значения. –

+0

Если я правильно помню, я хотел запретить подклассирование, потому что я хотел призвать пользователей api разбить вещи на повторно используемые, подключаемые части (не один гигантский подкласс подкласса ...), и я хотел заставить их реализовать абстрактный метод - тот, который обрабатывает входной сигнал и выводит результат. –

ответ

2

Что такое мотивация? Самая большая проблема, которую я вижу, заключается в том, что для Lion не является интуитивным, а AnimalFactory вместо Animal (к которому можно было бы обращаться с наименованием).

+0

В принципе, я не хочу, чтобы сами фабрики были использованы, чтобы что-то сделать, но приложить рычание к животному. И я не хочу, чтобы кто-либо использовал какой-либо подтип Animal. Я бы хотел использовать любую животную фабрику, которую я хочу, может быть, просто однажды обратился к Animal.class как к намеку. –

+0

oops ... от «Animal.class» Я имел в виду Animal.Factory.class ... что передано для создания (Class factoryClass) –

10

Confused? Почему у Animal нет публичного конструктора, который принимает Growl? Не стоит беспокоиться о том, как он был создан.

+0

Я не хочу, чтобы Growl мог быть использован напрямую. –

+0

Почему бы и нет? Если вы хотите ограничить конструкцию ограниченным набором классов, сделайте доступ по умолчанию для конструктора («private package»). –

+0

Но я хочу, чтобы Growl был реализован свободно в любом пакете. –

4

Я пытался создать фабрику (в Java), который запрещает подклассов фабричного продукта и предотвращает конкретные заводы от использования кем-либо, кроме абстрактной фабрики. Что вы думаете об этом ...

Что вы создали, это класс, запрещающий подклассификацию, а не фабрику, которая запрещает подклассификацию фабричного продукта. Хотя тонкий, это важная разница.

Если это для домашней работы, то я думаю, что причина вопроса - спорный вопрос, но при нормальных обстоятельствах я был бы очень подозрительным в причине того, что делал что-то подобное. Какую проблему вы пытаетесь решить? В конце концов, это цель кода.

+0

Я предполагаю, что я пытаюсь создать класс с помощью виртуального частного метода. И когда классы реализуют этот виртуальный частный метод, они становятся окончательными. –

+0

Кроме того, я пытаюсь обеспечить, чтобы подтипы класса с виртуальными частями не показывались. –

+0

И нет, я не студент, это просто проблема, которая прослушивает меня на некоторое время, и у меня было время простоя на работе сегодня. –

0

Не знаю, почему вам это нужно ... но в любом случае

Вы можете поставить завод и классы продукта в одном пакете. Затем измените класс продукта на предмет защиты пакета. Вуаля.