Как Вы кодировали бы стиральную машину?

Предположите, что у меня есть класс, который представляет простую стиральную машину. Это может выполнить следующие операции в следующем порядке: включите-> промывка->, центрифуга-> выключает. Я вижу две основных альтернативы:

  1. У меня может быть класс WashingMachine с методами turnOn (), промывка (международные минуты), центрифуга (международные версии), turnOff (). Проблема с этим состоит в том, что интерфейс ничего не говорит о правильном порядке операций. Я могу в лучшем случае бросить InvalidOprationException, если клиент пытается центрифугировать, прежде чем машина была включена. Я могу также использовать отдельный класс Программы, который передаст версии центрифуги и промоет минуты к WashingMachine и упростит эти методы.

  2. Я могу позволить самому классу заботиться о корректных переходах и иметь отдельный метод nextOperation (). Проблема с этим, с другой стороны, то, что семантика плоха. Клиент не будет знать то, что произойдет, когда он назовет nextOperation (). Предположите реализацию события щелчка кнопки центрифуги, таким образом, оно называет nextOperation (). Пользователь нажимает кнопку центрифуги после того, как машина была включена и взлеты! машина начинает промывать. Мне, вероятно, будут нужны несколько свойств на моем классе для параметризации операций или возможно отдельного класса Программы с washLength и centrifugeRevs полями, но это не действительно проблема.

Какая альтернатива лучше? Или возможно существует некоторый другой, лучшие альтернативы, которые я пропустил для описания?

11
задан Bill the Lizard 16 September 2012 в 22:26
поделиться

10 ответов

Я думаю, что turnOn(), wash(), centerfuge() и т.д. должны быть приватными/защищенными методами. Публичный интерфейс должен быть doTheWash(WashMode mode). Стиральная машина сама знает, какие режимы она поддерживает и как заставить их работать, пользователю стиральной машины не нужно вмешиваться в порядок или продолжительность операций. Разумно ожидать, что автор класса стиральной машины будет вызывать приватные методы в разумном порядке.

4
ответ дан 3 December 2019 в 05:33
поделиться

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

В любом случае машина имеет дополнительные подсистемы, и контроллер уведомляет подсистемы о выполнении некоторых действий, таких как запереть дверь , нагреть воду до 40 ° C или вращать барабан .

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

Если вы посмотрите на систему стирки с этой точки зрения, вы можете использовать шаблон Command внутри контроллера для моделирования программы стирки и шаблон Observer для уведомление подсистем (Например: Дверной переключатель слушает контроллер для сигнала, чтобы заблокировать дверь ).

1
ответ дан 3 December 2019 в 05:33
поделиться

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

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

0
ответ дан 3 December 2019 в 05:33
поделиться

В последнее время я перехожу на функциональный и использую неизменяемые объекты с Martin Fowler/JQuery chaining fluent style.

  • Я использую систему типов как можно чаще, поскольку она облегчает рефакторинг.
  • С моим методом компилятор заставит вас делать все правильно.
  • Поскольку объекты в некоторой степени неизменяемы, легче доказать, что математически эта машина состояний детерминирована.

код:

public class Washer {
    public void exampleRun() {
        new On()
            .wash(30)
            .spin(100)
            .turnOff();
    }
    public abstract static class State {}
    public static class On extends State {
        public Wash wash(int minutes) {
            return new Wash(minutes);
        }
    }
    public static class Wash extends State {
        private int minutes;
        public Wash(int minutes) {
            super();
            this.minutes = minutes;
        }

        public Spin spin(int revs) {
            return new Spin(revs);
        }

    }
    public static class Spin extends State {
        private int revs;
        public Spin(int revs) {
            super();
            this.revs = revs;
        }
        public Off turnOff() {
            return new Off();
        }
    }
    public static class Off extends State{}
}
0
ответ дан 3 December 2019 в 05:33
поделиться

Большинство западных стиральных машин используют таймер для перехода от цикла к циклу. Этот таймер можно рассматривать как своего рода машину состояния. Однако важно понимать, что стиральная машина управляет собой, а не пользователем. Пользователь устанавливает начальный режим, а затем она продолжает заниматься своими делами.

Итак, внутри у вас могут быть частные функции Wash, Rinse, Spin, фактический интерфейс будет SetCycle() и Start() и Stop(). У вас также могут быть некоторые дополнительные свойства, такие как уровень воды, скорость перемешивания, температура воды и т.д..

Старт вызывает продвижение времени, которое через некоторое время переходит в следующее состояние, пока, наконец, не завершится.

1
ответ дан 3 December 2019 в 05:33
поделиться

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

0
ответ дан 3 December 2019 в 05:33
поделиться

На моей стиральной машине у вас есть доступ к двум ручкам. Я немного смущен тем, какие ограничения существуют в вашем случае.

  1. Размер загрузки (малый, средний, большой)
  2. Ручка цикла (химическая завивка, трикотаж и тонкое белье, обычная)
    • Каждый цикл содержит разные «фазы», ​​на которых он может быть активирован в

. Когда вы «активируете» цикл (поворотом ручки), машина начнет работать, если вы повернете ее в середину или начало цикла. цикл.

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

class WashingMachine
{
    public void Activate(Cycle c, LoadSize s);
    ...
}
0
ответ дан 3 December 2019 в 05:33
поделиться

Я бы создал класс State Machine высокого уровня, который контролирует вход/запуск/выход из каждого состояния (где состояния могут быть такими, как "наполнение", "стирка", "полоскание", "опорожнение", "сухой отжим" и т.д.)

Нарисуйте диаграмму перехода состояний всех состояний, которые вам нужны, включая (для каждого состояния)

  1. какие требования существуют перед входом в состояние (условия входа)
  2. что должно произойти при входе в состояние (действия при входе)
  3. что происходит во время состояния (сама задача)
  4. какие требования существуют перед выходом из состояния (условия выхода)
  5. что происходит при выходе из состояния (действия при выходе)

Вам могут понадобиться или не понадобиться условия входа/выхода (напр. например, в некоторых случаях вы можете принудительно ввести условия с помощью действия входа/выхода). Однако в целях безопасности некоторые условия могут быть полезны (например, выход из состояния "ожидания" или вход в "опасное" состояние, такое как spin dry)

Вы также создаете Переходы, которые определяют связи между состояниями. Переход имеет

  1. состояние "из"
  2. состояние "в"
  3. условия перехода (может ли произойти переход?
  4. действия перехода (что должно произойти при переходе)

Опять же, вам может не понадобиться все это, и для многих переходов будут указаны только состояния "из" и "в".

В обоих случаях старайтесь, чтобы каждое Состояние и Переход были настолько простыми, насколько это нужно (старайтесь размещать условия/действия там, где они имеют наибольший смысл, Очевидно, что существует потенциальная возможность удвоения их определения в State и Transition из-за общего дизайна)

На данный момент должно быть довольно очевидно, что вы можете сделать довольно общий класс State, который включает абстрактные/перегружаемые функции для всех этих вещей, и аналогично для класса Transition. Класс State Machine может вызывать каждую из этих функций-членов по мере необходимости, основываясь на запрошенных им переходах.

Если вы делаете его особенно общим, то Состояния и Переходы могут быть зарегистрированы в State Machine во время построения, или вы можете просто закодировать State Machine, чтобы она содержала их все.

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

По моему опыту работы с подобными вещами, хорошей идеей является разделение высокоуровневой логики намеренного порядка/времени каждого действия и низкоуровневой логики реакции на какое-то аппаратное событие (например, переход из состояния "наполнения" при достижении уровня воды).

Однако это действительно общая конструкция, и вы можете достичь точно такой же функциональности множеством различных способов - редко существует единственный правильный способ делать вещи...

15
ответ дан 3 December 2019 в 05:33
поделиться

Вариант А похож на ручную стиральную машину, а вариант Б - на автоматическую стиральную машину. Оба варианта полезны для своих целевых пользователей:

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

Пользователь варианта B может наслаждаться простотой и писать фиктивные сериалы - обучи себя стирке за 21 секунду:-)

.
0
ответ дан 3 December 2019 в 05:33
поделиться

Эээ, немного странно, но начнем:

Я бы посмотрел даже на делегатов. Таким образом, для конкретного типа цикла стирки: вертикальной, легкой, быстрой, экономичной и т. Д. Я бы назвал интерфейс для каждого из них.

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

Тип стирки тогда будет иметь событие стирки, которое по порядку делегирует выполняемые циклы.

0
ответ дан 3 December 2019 в 05:33
поделиться