Лучший дизайн? Один и тот же объект, разные возможные состояния

StackOverflow https://stackoverflow.com/questions/1817715

Вопрос

У меня есть очень простое приложение, которое состоит из сайта переднего плана ASP.NET, а служба Windows WCF выполняет сложную внутреннюю логику.

У пользователя есть одна простая страница, где он выбирает некоторые параметры и нажимает кнопку «Отправить». Страница вызывает службу WCF и передает ей параметры. Служба создает экземпляр класса «Job», отправляя параметры конструктору, а затем вызывает метод «Run ()», который выполняет всю работу - вставляет запись «job» в базу данных с именем пользователя, временем запущен и т. д. Делает запрос стороннему поставщику, получает данные, помещает их в базу данных, выполняет другую бизнес-логику, а затем отмечает работу как выполненную.

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

Теперь перейдем к моему вопросу - поэтому у меня есть класс Job, в котором есть все упомянутые выше поля, а также его открытый метод Run () и конструкторы. Он имеет несколько простых закрытых функций и несколько закрытых членов, которые являются интерфейсами к таким классам, как IParser, IVendorConnection, IDataAccess - классы, которые выполняют всю фактическую работу, описанную выше ... реальный класс Job и метод Run () не делают много фактическая работа, в основном просто делегирует работу ее составным объектам (кроме всего прочего, обеспечивает хорошую тестируемость).

Теперь этот класс Job имеет 3 различных возможных использования / состояния. Его основное использование находится внутри Сервиса, для использования функции Run () для буквального запуска задания. У него также есть два других применения - выступать в качестве модели для панели, которую я описал выше, и выступать в качестве модели для поля со списком, которое я описал выше. Класс задания имеет 3 открытых конструктора, каждый из которых настраивает его на одно из 3 состояний. Во всех случаях каждое отдельное «государство» заботится только об определенных участниках, о которых другие 2 государства не заботятся - в некоторых случаях некоторые из членов используются во всех 3 государствах. «Состояние поля со списком» является самым простым - в этом случае я хочу только 3 поля только для чтения. В «состоянии панели» я забочусь о 6 полях только для чтения… в состоянии «работа» я в основном создаю эти значения полей по мере выполнения задания - и все они должны быть частными.

Я просто ищу более чистый способ сделать это. Если я создаю экземпляр класса Job в состоянии A, я знаю , что доступ к члену X не будет работать или вызов функции Y завершится неудачно. Однако это все еще скомпилированный код.

Я уверен, что другие сталкивались с этой проблемой раньше. Я думал о том, чтобы иметь базовый класс Job, помеченный как MustInherit / abstract, а затем иметь 3 производных класса, по одному для каждого состояния. Поместите общие члены в базу и специфичные для состояния в производную, и просто используйте производные классы в моем коде, где это уместно. Это кажется достаточно простым для моих целей и решает мою проблему. Возможно, у меня также может быть какой-то JobFactory ... Я думаю, я просто ищу, как другие люди решили это, может быть, я не думаю, что достаточно нестандартно ... У меня было много классов до конечных автоматов в моем дни разработки игр для любителей - но это было по-другому, потому что экземпляры этих классов могли изменять состояния (например, у класса «Враг» могло быть изменено его состояние с «attack_mode» на «ожидание»). В моем случае нет изменений состояний - После создания Иов должен оставаться в своем состоянии и никогда не пытаться вести себя по-другому. Отслеживание состояния и создание исключений, если метод / элемент используется, когда он не находится в заданном состоянии, кажется хрупким и слишком трудоемким. Любые предложения, основанные на том, как вы решили эту проблему раньше? И что я пытаюсь сделать излишним? Если работа

Это было полезно?

Решение

Ваша идея создать одно задание базового класса с 3 производными классами звучит точно так же, как и я. Создание JabFactory может помочь в этом дизайне. Это может быть плохой практикой создание объекта, где части объекта не используются, или незаконное использование при определенных обстоятельствах. Таким образом, создание производных классов только с необходимыми частями, безусловно, лучший дизайн. Это не излишество.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top