Методы в объектно-ориентированном дизайне - PullRequest
8 голосов
/ 25 октября 2010

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

Это имеет тенденцию генерировать диаграмму классов с актерами, которые имеют все действия, и внутренними классами, которые содержат только данные.

Это не кажется правильным. Есть ли другой способ думать о том, как моделировать объекты?

Q2. Кроме того, курс, кажется, подчеркивает моделирование объектов после их реальных аналогов, но это не обязательно имеет смысл в модели предметной области. IE. В медицинской практике они имеют Patient: CreateAppointment(), CancelAppointment(), но это не так, как это было бы реализовано (вместо этого вы бы изменили коллекцию посещений). Есть ли другой способ думать об этом?

Пример Q1

Секретарь: RecordAppointment (), RecordAppointmentCancellation ()

Назначение: время, дата, ... (без методов)

Пример Q2

Доктор: SeePatient ()

Хотя SeePatient является вариантом использования, он не имеет смысла для метода реального класса. Как вы думаете об этом?

Ответы [ 4 ]

10 голосов
/ 25 октября 2010

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

они рекомендуют подумать о том, что объект может сделать для своего метода и каковы его обязанности для его атрибутов

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

Например, руководство хорошо работает с этим объектом:

public class Tree
{
    public int Height { get; set; }
    public void Grow(int byHowMuch)
    {
        Height += byHowMuch;
    }
}

Хотя это, безусловно, отвечает всем требованиям, вы имеете право думать, что это «не правильно»:

public class Secretary
{
    public void MakeAppoinment(Patient patient)
    {
        //make the appointment
    }
}

Так в чем же решение? Дело в том, чтобы взять то, чему вас учат, и применить это. Изучение и понимание шаблонов проектирования очень поможет в разработке систем, которые более функциональны, чем дерево, которое знает, как расти.

Рекомендуемое чтение:

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

Переполнение стека имеет несколько связанных вопросов, которые могут быть полезны:

Дополнительно было бы неплохо проверить:

Наконец, нет единого определения того, что делает объект приложения ориентированным. То, как вы применяете шаблоны, принципы и т. Д., Определит вашу программу. Тот факт, что вы задаете себе эти вопросы, показывает, что вы на правильном пути.

0 голосов
/ 29 февраля 2012

Я все еще испытываю замешательство: «Я говорю вам делать что-то еще» или «Я делаю что-то, что кто-то еще попросил меня»?

Возможно, все, что вам нужно сделать, - это сыграть Барби или Г.И.Джо, чтобы понять взаимодействие объекта и куда идут обязанности.Г.И. Джо получил ранение (или Барби сломала гвоздь), поэтому он звонит в кабинет доктора.«Эй, док, это Джо, мне нужна встреча».Таким образом, вы, ребенок, говорите Барби пойти к врачу, который должен знать документ для вызова и способ вызова - справочный и публичный метод MakeAppointment ().Офис доктора должен записать встречу в книги - это собственный метод BookAppointment (), который является процедурой офиса для обработки запросов на встречу.

public abstract GenderAppropriateDolly {
     protected DrOffice  Drkilldare;
     public override MakeAppointment() {throw new NotImplementedException();}
}


public class GIJoe : GenderAppropriateDolly {
    DrKilldare = new DrOffice();
    List<Appointment> myAppointments = new List<Appointment>;

    public void MakeAppointment () {
        myAppointments.Add(DrKilldare.BookAppointment(this));
    }
}

public class DrOffice {
    List<Appointment> officeAppointments = new List<Appointments>;

    public Appointment BookAppointment(GenderAppropriateDolly forWhom) {
       Appointment newappt = new Appointment(formWhom);
       this.Appointments.Add(newappt);

       return newappt;
    }    
}

public class Kid {
    GenderAppropriateDolly myRoleModel = new GIJoe();

    // Joe got wounded so ...
    myRoleModel.MakeAppointment();
}
0 голосов
/ 11 декабря 2010

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

Вы можете моделировать это поведение в классах как статические методы, которые работают с моделью данных. Это не OO, но это нормально. Вы можете сгруппировать связанные методы вместе в такие классы, и вскоре у вас появится понятие «сервисы», как в сервис-ориентированном программировании.

В Java существуют спецификации и стандарты для создания таких классов, а именно сессионный компонент без сохранения состояния в EJB. Spring Framework имеет сходные понятия со стереотипом «Служба», который можно применять к классам, чтобы помечать их как фасады для бизнес-логики.

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

Архитектура DCI является формализацией этого и попыткой сделать то же самое, но в то же время пытаясь оставаться верными ориентации объекта, добавляя поведение к объектам так, как им нужно. *

0 голосов
/ 25 октября 2010

Q1 Возможно ли, что обязанности ваших объектов должны быть истолкованы как требования авторизации или контракта, а также какие действия они должны предпринять?Итак, чтобы взять медицинский пример из вашего Q2, объект с ролью планировщика (например, интерфейс C # / Java или протокол Obj-C) имеет атрибуты вокруг CanEditAppointments или EditsAppointments.

Q2 С точки зрения варианта использования пациент может иметь возможность создать встречу, и поэтому вы можете внедрить пациента в вашу объектную модель с помощью метода CreateAppointment ().Но с точки зрения инкапсуляции вы, скорее всего, создадите экземпляр объекта Appointment в CreateAppointment (), а затем вызовете методы или зададите свойства объекта Appointment, чтобы установить его время, дату, пациента, врача и т. Д.

Ипоскольку коллекция Appointment, вероятно, будет постоянным хранилищем, таким как база данных, вероятно, объект Appointment будет обязан добавить себя в коллекцию (Appointment.Schedule () проходит через слой доступа к данным, чтобы сохранить себя в базе данных).

Это также связано с вашим Q1, поскольку ответственность за объект Appointment состоит в том, чтобы сохранить себя, поэтому он может реализовать интерфейс ISaveAppointment, для которого требуются поля и методы для его выполнения.Назначение также должно иметь дату, время, пациента и т. Д. Перед сохранением, поэтому интерфейс ISaveAppointment должен требовать их существования, а Appointment.Schedule () должен проверять правильность значений или их ранее.ПРОВЕРЯЕМЫЕ.

...