Я разрабатываю приложение, которое будет использоваться для открытия и закрытия клапанов в промышленной среде, и подумывал о чем-то простом, как это:
public static void ValveController
{
public static void OpenValve(string valveName)
{
// Implementation to open the valve
}
public static void CloseValve(string valveName)
{
// Implementation to close the valve
}
}
(Реализация будет записывать несколько байтов данных в последовательный порт для управления клапаном - «адрес», полученный из имени клапана, и либо «1», либо «0», чтобы открыть или закрыть клапан).
Другой разработчик спросил, нужно ли нам вместо этого создавать отдельный класс для каждого физического клапана, которых насчитывается десятки. Я согласен, что было бы лучше писать код, PlasmaValve.Open()
а не ValveController.OpenValve("plasma")
, но это перебор?
Кроме того, мне было интересно, как лучше решить проект с учетом нескольких гипотетических будущих требований:
- Нас просят поддержать клапан нового типа, для открытия и закрытия которого требуются разные значения (не 0 и 1).
- Нас просят поддержать клапан, который можно установить в любое положение от 0 до 100, а не просто «открыть» или «закрыть».
Обычно я бы использовал наследование для такого рода вещей, но недавно я начал думать о «композиции поверх наследования» и задавался вопросом, есть ли более подходящее решение для использования композиции?
источник
Ответы:
Если каждый экземпляр объекта вентиля будет выполнять тот же код, что и этот ValveController, то кажется, что несколько экземпляров одного класса - правильный путь. В этом случае просто укажите, каким клапаном он управляет (и каким образом) в конструкторе объекта клапана.
Однако если для управления каждым клапаном требуется свой код, а текущий ValveController выполняет гигантский оператор switch, который делает разные вещи в зависимости от типа клапана, то у вас плохо реализуется полиморфизм. В этом случае перепишите его нескольким классам с общей базой (если это имеет смысл), и пусть принцип единой ответственности будет вашим руководством по проектированию.
источник
Моя главная задача - использовать строки для параметра, идентифицирующего клапан.
По крайней мере, создайте
Valve
класс, который имеетgetAddress
в форме основные потребности реализации, и передайте их классуValveController
и убедитесь, что вы не можете создать несуществующие клапаны. Таким образом, вам не придется обрабатывать неправильные строки в каждом из методов открытия и закрытия.Создавать ли вы удобные методы, которые вызывают открытие и закрытие,
ValveController
зависит от вас, но, если честно, я бы оставил все коммуникации с последовательным портом (включая кодирование) в одном классе, который другие классы будут вызывать при необходимости. Это означает, что когда вам нужно перейти на новый контроллер, вам нужно изменить только один класс.Если вам нравится тестировать, вы также должны сделать
ValveController
синглтон, чтобы вы могли его высмеять (или создать тренажер для операторов).источник