Лучший способ реализовать Шаблон "фабрика" в Java

Мне очень трудно понять, почему Enterprise Service Bus, фундаментальный монолит, может использоваться в микросервисной архитектуре.

blockquote>

ESB имеет несколько возможностей, полезных для микросервисной архитектуры. Он позволяет:

  • передачу и преобразование сообщений, см. Корпоративные интеграционные шаблоны
  • применение межсервисных политик (например, защита на уровне сообщений, авторизация, ..) [ 112]
  • отделение конечной точки службы от ее реализации (управление версиями службы)
  • предоставляет такие стандартные услуги, как обмен сообщениями, обработка событий, мониторинг, хедлинг исключений и т. Д.
  • смягчение двухточечной связи
  • .. еще немного ..

Действительно, ESB обычно работает как отдельное приложение (или контейнер в вашем случае) и, реализовав все возможности, это не всегда самое легкое приложение (по сравнению с простыми одноцелевыми микросервисами). При правильной реализации ESB должен оказывать минимальное влияние на задержку ответа или нагрузку на инфраструктуру.

Предоставление стандартных услуг и межсервисных возможностей. ИМХО, вы можете рассматривать ESB не как отдельный сервис, а как часть инфраструктурных сервисов, используемых в реализации микросервисов.

Возможно, Apache Camel используется для оркестровки? Но это противоречит духу микросервисов.

blockquote>

Apache Camel - это фреймворк, он может использоваться внутри приложений, автономно или также есть продукты ESB, построенные поверх Apache Camel (RedHat Fuse ESB, Talend ESB, Apache ServiceMix, ..).

5
задан 5 revs, 2 users 95% 14 August 2018 в 10:13
поделиться

5 ответов

Обратите внимание, что некоторые из других ответов могут возможно описать фабрики, но не описывают Шаблон "фабрика" GOF.

Теперь я хочу заменить эту строку Шаблоном "фабрика", хотя я не уверен, поскольку мой конструктор TestMode требует дополнительного объекта, и я не уверен, куда я должен был бы передать это значение.

Ну, Вы могли думать о нем этот путь: MainMode, не TestMode, является тем, который делает специальную вещь. Специальная вещь, которую это делает, должен проигнорировать данное число, чтобы удостовериться, что это действительно случайно. Таким образом размышления об этом, это - MainMode, который делает что-то дополнительное.

Или, если бы кроме случайности, MainMode и TestMode не отличаются, то Вы думали бы, возможно, что можно факторизовать то подобие в один класс, которому предоставляют одну из двух Стратегий вычисления случайных чисел. Одна Стратегия на самом деле была бы случайна, и можно было бы быть извращенным со случайным диапазоном только 1 значения.

Но давайте предположим, что существуют другие различия между MainMode и TestMode - по-видимому, выводы TestMode дополнительная отладка к System.out или чему-то.

Мы можем все еще факторизовать, "как мы предоставляем случайность", от мы тестируем или играем в игру для реального". Это ортогональные проблемы.

Таким образом, теперь мы знаем, что в дополнение к тому, что делает 'Режим, он должен принять Стратегию Случайности. Затем мы могли, например, когда Вам говорят, что стандартная случайная платформа не достаточно действительно случайна, можно заменить ее лучшим случайным.

Или можно сделать тестирование, где диапазон randoms ограничивается только к двум вариантам, или всегда чередуется от одного для обнуления или возвращает на каждом вызове следующее значение в некотором Vecrtor или Iterator.

Таким образом, мы используем Стратегическую модель GOF для создания стратегий случайности:

interface RandomStrategy { 
  public double random();
}

public class NotSoRandom implements RandomStrategy {
  private double r;
  public NotSoRandom( final double r ) { this.r = r; }
  public double random() { return r; }
}

public class PlatformRandom implements RandomStrategy {
  public double random() { return Math.random(); }
}

Теперь, если Ваше целое приложение только когда-либо создает один 'Режим, нет никакой потребности в фабрике; Вы используете фабрику, когда необходимо создать тот же тип класса много раз; Фабрикой является на самом деле просто Стратегия создания правильного вида (sub) класса.

В производственном коде я использовал фабрики, где у меня есть некоторый универсальный класс, который создает материал, и я должен сказать, как создать правильный подкласс для создания; я передаю на фабрике, чтобы сделать это.

Теперь мы создаем Шаблон "фабрика" для 'Режима; это будет удивительно подобно Стратегической модели:

abstract class Mode() {
 private RandomStrategy r;
 public Mode( final RandomStrategy r ) { this.r = r; }
 // ... all the methods a Mode has
}

public class MainMode implements Mode {
  public MainMode( final RandomStrategy r ) { super(r); }
}

public class TestMode implements Mode {
  public TestMode( final RandomStrategy r ) { super(r); }
}

interface ModeFactory{ 
  public Mode createMode( final RandomStrategy r );
}

public class MainFactory() {
  public Mode createMode( final RandomStrategy r ) {
      return new MainMode(r);
  }
}

public class TestFactory() {
  public Mode createMode( final RandomStrategy r ) {
      return new TestMode(r);
  }
}

Таким образом, теперь Вы знаете о Шаблоне "фабрика" и Стратегической модели, и как они подобны в "форме", но отличаются в том, как они используются: Шаблон "фабрика" является Объектным Creational и возвращает объект, который будет использоваться; Стратегия является Поведенческим Объектом, и экземпляр обычно создается явно, и ссылка, как сохранилось, к экземпляру, инкапсулирует алгоритм. Но с точки зрения структуры, они весьма схожи.

Править: OP спрашивает в комментарии, "Как я интегрировал бы это в свой GUI?"

Ну, ни одно из этого не принадлежит GUI Вашей программы, кроме возможно 'Режима. Вы создали бы ConcreteStrategy и передали бы его предпочтительной Фабрике в некоторой стандартной программе установки, возможно определив, чтобы использовать на основе параметров командной строки или файлов конфигурации. в основном Вы выбрали бы корректную фабрику очень как Вы выбирающий корректный класс в Вашем исходном сообщении. Снова, если Вы только когда-либо создаете одно из чего-то, Вам не нужна Фабрика; фабрики для массового производства (или семейства созданий связанных конкретных типов - хотя это выходит за рамки этого вопроса).

(Предположите, что у нас есть игра, где пользователь может выбрать на командной строке, бороться ли с роботами или драконами; затем мы хотели бы инстанцировать OpponentFactory, которые производят Противников (интерфейс), с производными классами RobotOpponent и DragonOpponent, и передают ту фабрику части игры это spawnsNewOpponent (). Точно так же пользователь мог бы выбрать храбрых или трусливых противников, которых мы настроили как Стратегия. Мы не должны делать больше экземпляров Стратегии, поскольку Стратегия является обычно идемпотентом (не сохраняющий состояние и одиночный элемент).)

static int main( String[] args ) {
// setup game world

final RandomStrategy r = "random".equals(args[0]) 
  ? new PlatformRandom() : new  NotSoRandom( Integer.intValue(args[0]) ) ;
// notice the simlarity to the code you originally posted;
// we factored out how to achieve "randomness" as a Strategy.

// now we will use our Strategy to setup our Factory;

final ModeFactory f = "test".equals(args[1])
  ? new TestFactory(r) : new MainFactory(r);
// also similar to your code
// we've just added an extra level of indirection: 
// instead of creating a Mode, we've created an object that can create Modes
//  of the right derived type, on demand.

// call something that uses our factory
functionThatRunsameAndNeedstoProduceModesWhenevertNeedsTo( f ); 

}
12
ответ дан 18 December 2019 в 14:51
поделиться

Смысл Фабрики - то, что она должна иметь необходимое состояние для создания Игры соответственно.

Таким образом, я создал бы фабрику как это:

public class GameFactory {
   private boolean testMode;

   public GameFactory(boolean testMode) {
     this.testMode = testMode;
   }

   public Game getGame(int numberRanges, int numberOfGuesses) {
     return (testMode) ? new MainMode(numberRanges, numberOfGuesses) : 
       new TestMode(numberRanges, numberOfGuesses, getRandom());
   }

   private int getRandom() {
     . . . // GUI code here
   }
}

Теперь можно инициализировать эту фабрику где-нибудь в приложении и передать его в любому коду, должен создать Игру. Этот код теперь не должен волноваться, о каком режиме это, и передача дополнительных случайных параметрических усилителей - он использует известный интерфейс для создания Игр. Все необходимое состояние усвоено объектом GameFactory.

1
ответ дан 18 December 2019 в 14:51
поделиться

Попробуйте что-то как,

abstract class ModeFactory {

    public static Mode getMode(isMode, numberRanges, numberofGuesses) {
        return isMode ? new MainMode(numberRanges, numberofGuesses) : new TestMode(numberRanges, numberOfGuesses, randNo());
    }

    public static Mode getMode(isMode, numberRanges, numberofGuesses, someNumber) {
        return isMode ? new MainMode(numberRanges, numberofGuesses) : new TestMode(numberRanges, numberOfGuesses, someNumber);
    }

}

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

0
ответ дан 18 December 2019 в 14:51
поделиться

Ваш код мог, вероятно, быть изменен в шаблон "фабрика".

Что-то как:

public static Mode createMode(boolean isMainMode)
{
    if(isMainMode) return new MainMode(...);
    return new TestMode(...);
}

Поместите этот метод, где-нибудь разумный (этот хитер, возможно, статический ModeFactory),

Это предполагает, что MainMode и TestMode являются подтипами того же типа (подклассы, или реализуйте интерфейс Mode),

Теперь вся игра должна сделать, назвать ModeFactory.createMode (...) и передать соответствующую булевскую переменную.

Редактирование (в ответ на обновление OP):

Ваш рэнд () оценен, прежде чем фактического конструктора вызывают, и он представляет GUI. Это то, что Вы подразумеваете под активацией себя?

Необходимо сделать проектное решение, где Вы хотите принять решение относительно режима. Если у Вас есть GUI, и у Вас есть модель, могло бы быть предпочтительно разработать GUI, чтобы знать, необходим ли вызов к случайному поколению (и всплывающее окно), прежде чем Вы назовете метод фабрики, и затем передадите случайное число методу фабрики и позволите ему просто выбрать корректного конструктора.

Наличие его наоборот (модель называет Ваш GUI) более хитро и вероятно плохая идея.

0
ответ дан 18 December 2019 в 14:51
поделиться
interface ModeFactory {
    Mode createMode(int numberRanges, int numberOfGuesses);
}

class MainModeFactory implements ModeFactory {
    Mode createMode(int numberRanges, int numberOfGuesses) {
        return new MainMode(numberRanges, numberOfGuesses);
    }
}

class TestModeFactory implements ModeFactory {
    Mode createMode(int numberRanges, int numberOfGuesses) {
        return new TestMode(numberRanges, numberOfGuesses, randNo());
    }
}

...

play = modeFactory.createMode(numberRanges, numberOfGuesses);

Таким образом при запуске Вы создаете соответствующую фабрику режима, передавая его в к тому, везде, где игра должна быть создана.

0
ответ дан 18 December 2019 в 14:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: