abstract class Notepad
{
public abstract bool AddNote(string text);
}
class BigNotepad:Notepad
{
public ovveride bool AddNote(string text)
{
//some logic
}
}
class SmallNotepad:Notepad
{
public ovveride bool AddNote(string text)
{
//another logic
}
}
Вызывающий код:
List<Notepad> notepades=getNotepades();
foreach(var np in notepades)
{
np.AddNote('sometext');
}
В подклассах метод AddNote добавляет текст, если это возможно, и выполняет еще кое-какую логику.
В рич модели все просто, весь код в методах соответствующих типов. И при итерации по колекции я просто вызываю метод. А как подобное сделать на анемике? Подскажите пожалуйста.
Здравствуйте, Аноним, Вы писали:
А>В домене имеем класс и его подклассы: А>... А>В рич модели все просто, весь код в методах соответствующих типов. И при итерации по колекции я просто вызываю метод. А как подобное сделать на анемике? Подскажите пожалуйста.
Я не бог весть какой архитектор в части Rich/Anemic, но сдается мне, что нужно для начала определиться какую функцию у тебя выполняет класс "Notepad" и его подклассы: хранит данные или агрегирует в себе методы обработки данных.
Допустим "Notepad" — хранит данные, т.е.
class Notepad
{
public string Field1 { get; set; }
public int Field2 { get; set; }
...
}
Тогда, с точки зрения Anemic, нужно завести второй класс, агрегирующий методы обработки Notepad:
class NotepadService
{
public abstract bool AddNote(Notepad mp, string text);
...
}
А вот в части наследования надо вообще еще очень хорошо подумать: надо ли оно в данном конкретном случае?
Если надо, то что именно должно наследоваться: контейнер данных (производные классы будут иметь дополнительные поля), или сервис (методы разные), или и то и другое.
В общем настледование — отдельная песня.
Красота — наивысшая степень целесообразности. (c) И. Ефремов
Здравствуйте, stomsky, Вы писали:
S>Здравствуйте, Аноним, Вы писали:
А>>В домене имеем класс и его подклассы: А>>... А>>В рич модели все просто, весь код в методах соответствующих типов. И при итерации по колекции я просто вызываю метод. А как подобное сделать на анемике? Подскажите пожалуйста. S>Я не бог весть какой архитектор в части Rich/Anemic, но сдается мне, что нужно для начала определиться какую функцию у тебя выполняет класс "Notepad" и его подклассы: хранит данные или агрегирует в себе методы обработки данных. S>Допустим "Notepad" — хранит данные, т.е. S>
class Notepad
S>{
S> public string Field1 { get; set; }
S> public int Field2 { get; set; }
S> ...
S>}
S>Тогда, с точки зрения Anemic, нужно завести второй класс, агрегирующий методы обработки Notepad: S>
class NotepadService
S>{
S> public abstract bool AddNote(Notepad mp, string text);
S> ...
S>}
S>А вот в части наследования надо вообще еще очень хорошо подумать: надо ли оно в данном конкретном случае? S>Если надо, то что именно должно наследоваться: контейнер данных (производные классы будут иметь дополнительные поля), или сервис (методы разные), или и то и другое. S>В общем настледование — отдельная песня.
Нет обязанности "хранит данные". Так вкратце говорят когда необходим объект, который переносит данные от источникаполучателю (типичный DTO, который может быть выражен типом Record в ФЯ). Если же у тебя ровно один класс работает с данными, то скорее всего нужно поместить данные в сам класс.
Кроме того не стесняйся использовать extension-методы.
Здравствуйте, gandjustas, Вы писали:
G>Нет обязанности "хранит данные". Так вкратце говорят когда необходим объект, который переносит данные от источникаполучателю (типичный DTO, который может быть выражен типом Record в ФЯ). Если же у тебя ровно один класс работает с данными, то скорее всего нужно поместить данные в сам класс.
Не буду спорить с более опытным в данном вопросе человеком.
Но прошу объяснить какая тогда обязанность у anemic-объекта в слое бизнес-логики?
Сказать, что он тупо транзитное звено между базой данных и клиентом нельзя, т.к. над с ним еще и некоторые сервисные классы работают. Причем результат работы этих сервисов совсем не обязательно будет передан клиенту. Возможно этот самый результат будет назад в базу возвращен, а клиент получит только код ошибки, чтобы отобразить пользователю: "Операция выполнена успешно".
По-моему, как раз получается, что этот самый anemic-объект является просто контейнером данных, вытянутых из базы...
Я ошибаюсь?
G>Кроме того не стесняйся использовать extension-методы.
+1 (соответствующая кнопочка почему-то отсутствует... )
Красота — наивысшая степень целесообразности. (c) И. Ефремов
S>Но прошу объяснить какая тогда обязанность у anemic-объекта в слое бизнес-логики? S>Сказать, что он тупо транзитное звено между базой данных и клиентом нельзя, т.к. над с ним еще и некоторые сервисные классы работают. Причем результат работы этих сервисов совсем не обязательно будет передан клиенту. Возможно этот самый результат будет назад в базу возвращен, а клиент получит только код ошибки, чтобы отобразить пользователю: "Операция выполнена успешно". S>По-моему, как раз получается, что этот самый anemic-объект является просто контейнером данных, вытянутых из базы... S>Я ошибаюсь?
Нету у anemic-"класса" никаких обязанностей. И быть не может, потому что выполнение обязанностей предполагает наличие методов. Называть обязанностью хранение данных я бы не стал. Это просто струкрура данных, которая гоняется от одной процедуры к другой, где потихоньку модифицируется. Называется данный подход — процедурное программирование.
G>>Кроме того не стесняйся использовать extension-методы. S>+1 (соответствующая кнопочка почему-то отсутствует... )
Здравствуйте, stomsky, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Нет обязанности "хранит данные". Так вкратце говорят когда необходим объект, который переносит данные от источникаполучателю (типичный DTO, который может быть выражен типом Record в ФЯ). Если же у тебя ровно один класс работает с данными, то скорее всего нужно поместить данные в сам класс. S>Не буду спорить с более опытным в данном вопросе человеком. S>Но прошу объяснить какая тогда обязанность у anemic-объекта в слое бизнес-логики?
У него обязанность передавать данные от хранилища (репозитария) до UI как одно целое. БЛ будет работать с такими объектами.
БЛ в anemic работает не с некоторыми объектами в смысле ООП, а с данными (как оно и есть на самом деле) выраженными в виде классов.
S>Сказать, что он тупо транзитное звено между базой данных и клиентом нельзя, т.к. над с ним еще и некоторые сервисные классы работают. Причем результат работы этих сервисов совсем не обязательно будет передан клиенту. Возможно этот самый результат будет назад в базу возвращен, а клиент получит только код ошибки, чтобы отобразить пользователю: "Операция выполнена успешно".
Ну а какая разница между чем передавать данные, хоть между BL и PL, хоть между UI и BL. Функция классов данных от этого не меняется.
S>По-моему, как раз получается, что этот самый anemic-объект является просто контейнером данных, вытянутых из базы... S>Я ошибаюсь?
Нет, оно так и есть. И очень хорошо что БД работает с данными, а не с какими-то черными ящиками. Потому что в таком случае мы можем явно управлять способом загрузки этих данных, транзакциями и другими вопросами. Более того, мы можем БЛ делать в виде отложенных запросов, которые выполняются на сервере БД. Это наиболее эффективный способ, в отличие от материализации объектов.
G>>Кроме того не стесняйся использовать extension-методы. S>+1 (соответствующая кнопочка почему-то отсутствует... )
Здравствуйте, gandjustas, Вы писали:
S>>По-моему, как раз получается, что этот самый anemic-объект является просто контейнером данных, вытянутых из базы... S>>Я ошибаюсь? G>Нет, оно так и есть. И очень хорошо что БД работает с данными, а не с какими-то черными ящиками.
А я разве спорю?!
Красота — наивысшая степень целесообразности. (c) И. Ефремов