2010-09-06 3 views
1

Я строю систему управления для установки оборудования (система циркуляции воды). Я разработал его в двух слоях: слое описания аппаратного обеспечения и уровне управления.Обратная зависимость между проблемами слоев

+----------------------------------------------+ 
| Control (enables manipulation of devices) | 
+----------------------------------------------+ 
     | uses (decorates) 
     v 
+---------------------------------------+ (de)serialize +------------+ 
|   HW Description    |<--------------->| Files/DB | 
| (stores physical layout, cabling etc) |     +------------+ 
+---------------------------------------+ 

Слой описания оборудования содержит карту оборудования, описывающую, как трубы подключены к теплообменникам и другому оборудованию. Данные для этого уровня настраиваются для каждой установки и будут прочитаны во время выполнения. Поэтому все классы на уровне описания аппаратного обеспечения должны быть сериализованы так или иначе (через Hibernate/serialization to XML или так).

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

В этой системе объекты в слое управления, возможно, придется искать их neirest соседей с помощью описания аппаратных средств, так что контроллер теплообмена может сделать что-то вроде

HeatExchangerController neighbour = this.getHeatExchanger().getInputPipe().getOtherSide().getHeatExchanger().getController(); 
neighbour.notify(highLoadAlert); 

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

Я немного застрял, пытаясь решить, хорошо ли это или плохой идеей сделать этот элемент управления доступным через слой описания HW, например, или если есть какие-то альтернативные подходы. Я могу только думать об одном методе, который включал бы зеркалирование и делегирование почти всего слоя описания HW, который кажется способным навязчивым быть хорошим.

Так что мой вопрос в том, что кто-либо из вас признает эту ситуацию и имеет какие-либо советы/опыты. У него есть имя? Существуют ли какие-либо хорошие шаблоны/передовые методы для этого, есть ли другие известные библиотеки/рамки, которые также были и работают вокруг этой ситуации?

спасибо.

ответ

0

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

Похоже, вы строите Anemic Domain Model?

+0

Хороший материал. Это то, о чем я думал, что это как-то неправильно. Самая большая проблема заключается в том, что действительно НЕ МОЖНО отделить данные от логики. Это может быть возможно в простых примерах, но есть действительно большая разница между описанием HW, которое должно быть в формате, который легко сериализуется, и логике. Поэтому можно также утверждать (согласно DDD), что у меня есть два поддомена, которые должны иметь две разные модели. –

+0

Почему это сложно? Почему вы не можете просто переместить методы контроллера в свои сериализуемые классы (или иначе сохраняемые)? Я не знаю, насколько я знаю, это связано с тем, что у классов есть методы, выходящие за рамки сеттеров и геттеров ... – meriton

+0

Обычно это сложнее, чем вы его описываете - сначала у вас есть другой аргумент модели, который я сделал, но технологии сериализации объектов часто предъявляют довольно высокие требования на объектах все свойства должны быть модифицируемыми (JAXB), порядок инициализации не определен, конструкторы не вызываются и т. д. и т. д. Он может работать в классической среде JPA, для общего графа объектов с более чем тривиальными взаимозависимостями и последовательности запуска быстро стремятся выйти из-под контроля ИМО. –

0

Возьмите подход, основанный на домене.

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

+0

Можете ли вы быть более конкретными? Если я посмотрю на свой конкретный сценарий, я не могу думать о каких-либо более гранулированных доменах, чем о «регулировании тепла». Что бы вы назвали доменами и контроллерами? –

+0

Я бы сказал, что каждое устройство связывается с другим через контроллер. –

+0

Извините, но я не понимаю, как это ускользает от описания HW, не могли бы вы уточнить? –

0

не слишком уверен, в чем ваша проблема. если вы не хотите getController() метод в классе вашего оборудования, вы можете хранить Оборудование-> отображение контроллера в слабой хэш-карта

public class Controller 

    static WeakHashMap<Hardware,Controller> map = ... 

    static public Controller of(Hardware hw){ return map.get(hw); } 

    Controller(Hardware hw) 
    { 
     map.put(hw, this); 
    } 

очень часто, люди любят, чтобы добавить «удобные» методы , не имея страха сложности в зависимости

user.getThis() 
user.getThat() 
user.getTheOthers() 

в то время как User класс является основным классом, он не должен иметь Knowlege в этом, что и другие. Теперь код lt ot зависит от класса User, а класс User зависит от многих других классов. Конечным результатом является то, что каждый класс приложения зависит от каждого другого класса, большого шара беспорядка.

+0

Точка взята. Но если у меня есть это отношение в любом случае, но косвенно, как вы показываете, это лучше? Может быть, у меня должны быть эти отношения. –

0

Это сложное решение, которое я имел в виду. Он добавляет украшение слой поверх слоя HW, который добавляет ссылки до уровня управления для каждого объекта HW:

                -+ 
+--------------------------+    +-----------------+ | 
| HeatExchangerController |    | PipeController |  > Controller Layer 
+--------------------------+    +-----------------+ | 
      ^1 controller      ^1 controller -+ 
      |          | 
      v 1 heatExchanger      v 1 pipe  -+ 
+---------------------------+ inputPipe 1 +------------------+ | 
| ControlAwareHeatExchanger |--------------| ControlAwarePipe | > Decorated HW Layer 
+---------------------------+ 1 otherSide +------------------+ | 
      |          |    -+ 
      v 1 realExchanger      v 1 realPipe -+ 
+---------------------------+ inputPipe 1 +------------+   | 
|  HeatExchanger  |--------------| Pipe  |   > HW Layer 
+---------------------------+ 1 otherSide +------------+   | 
                   -+ 

декорированный слой будет содержать код, как:

class ControlAwareHeatExchanger { 
    private final HeatExchanger realExchanger; 
    private final ControlAwarepipe inputPipe; 

    public ControlAwareHeatExchanger(HeatExchanger decoratee) { 
    realExchanger = decoratee; 
    inputPipe = new ControlAwarePipe(decoratee.getInputPipe()); 
    } 

    public ControlAwarePipe getInputPipe() { 
    return inputPipe; 
    } 

    ... 
}  

Таким образом, вы можете сделать:

ControlAwareHeatExchanger controlHE = heatExchangerController.getHeatExchanger(); 
ControlAwarePipe controlInputPipe = controlHE.getInputPipe(); 
ControlAwareHeatExchanger otherHE = controlInputPipe.getOtherSide(); 
HeatExchangerController otherController = otherHE.getController(); 

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

Но, как вы можете видеть, вам нужно отразить все соединения и украсить весь слой HW, чтобы добиться этого. Будет задействовано много делегаций. Мысли?

Смежные вопросы