【问题标题】:Methods in Object-Oriented Design面向对象设计中的方法
【发布时间】:2011-04-29 23:15:06
【问题描述】:

第一季度。 在我的面向对象建模和设计的大学研究中,他们建议考虑对象可以为它的方法做什么,以及它对它的属性的责任是什么。所有试图澄清的尝试都导致了进一步的混乱。

这往往会生成一个类图,其中包含具有所有操作的参与者和只保存数据的内部类。

这似乎不正确。是否有另一种思考如何为对象建模的方法?

第二季度。此外,该课程似乎强调在现实世界中对对象进行建模,但在领域模型中不一定有意义。 IE。在医疗实践中,他们有Patient: CreateAppointment(), CancelAppointment(),但这不是它的实施方式(您可以修改约会集合)。有没有其他的想法?

示例 Q1

秘书:RecordAppointment()、RecordAppointmentCancellation()

约会:时间、日期、...(无方法)

示例 Q2

医生:SeePatient()

虽然SeePatient 是一个用例,但它对于实际类上的方法没有意义。你怎么看这个?

【问题讨论】:

  • 没有一成不变的方法。它过度简化了所有不同的有效方法,只考虑car.wheelCount。例如,在约会的情况下,doctorsOfficeSchedule.createAppointment(patient, ...) 似乎更“清楚”。也就是说,我倾向于面向数据与“面向对象”。

标签: oop class-design analysis


【解决方案1】:

不幸的是,您遇到的障碍在学术界太典型了。学术项目往往从视频租赁商店、图书馆或学生注册系统开始(你的与医生办公室不同),然后用动物教授继承。你提供的指南也很典型

他们建议考虑一个对象可以为它的方法做什么,以及它对它的属性的责任是什么

事实上,当初学者问我时,我通常会解释一个对象的属性是它知道自己的事情,它的方法是它知道如何做的事情。这实际上只是另一种表达你所拥有的东西的方式。正如您发现的那样,当您开始讨论更具体的系统而不仅仅是示例时,这种思维方式很快就会崩溃。

例如,该指南适用于这个对象:

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
    }
}

那么解决方法是什么?这是一个把你所学的东西拿来并应用它的问题。学习和理解design patterns 将有助于开发比知道如何生长的树更实用的系统。

推荐阅读:

为了解决您遇到的问题,我可能会使用继承的人员类和接口的组合,它们将通过一系列服务类执行它们的操作。本质上,秘书、医生和患者都将从 person 继承,并且这些类中的每一个都可以传递给伴随的服务类。服务类可能会也可能不会做类似SeePatient() 的事情。请不要拿这个例子来表示 person 类没有方法。

Stack Overflow 有很多相关的问题可能有用:

另外,最好去看看:

最后,对于什么使应用程序面向对象没有一个单一的定义。你如何应用模式、原则等将定义你的程序。你问自己这些问题的事实表明你走在正确的轨道上。

【讨论】:

    【解决方案2】:

    第一季度 您的对象的责任是否应该被解释为授权或合同要求,就像他们应该采取的行动一样?因此,以 Q2 中的医学示例为例,具有调度程序角色的对象(想想 C#/Java 接口或 Obj-C 协议)具有围绕 CanEditAppointments 或 EditsAppointments 的属性。

    第二季度 从用例的角度来看,患者可能能够创建约会,因此您可以在对象模型中使用 CreateAppointment() 方法实现 Patient。但是,在封装方面,你可能会在 CreateAppointment() 中实例化一个 Appointment 对象,然后在 Appointment 对象上调用方法或设置属性来设置它的时间、日期、患者、医生等。

    由于 Appointment 集合很可能像数据库一样是永久存储,因此 Appointment 对象可能负责将自身添加到集合中(Appointment.Schedule() 会通过您的数据访问层将自身保存到数据库中) )。

    这也与您的 Q1 相关,因为 Appointment 对象的职责是保存自己,因此它可能实现一个 ISaveAppointment 接口,该接口需要字段和方法来执行它。在保存之前拥有日期、时间和患者等也是 Appointment 的责任,因此 ISaveAppointment 接口应该要求它们存在,并且 Appointment.Schedule() 应该验证这些值是否正确或之前已经存在验证。

    【讨论】:

      【解决方案3】:

      您是对的,在许多情况下,存在更自然地包含行为的更高阶事物,例如系统或用户。

      您可以在类中将此行为建模为对数据模型进行操作的静态方法。这不是OO,但没关系。您可以将相关的方法组合到这样的类中,很快您就会拥有“服务”的概念,就像在面向服务的编程中一样。

      在 Java 中有用于创建此类类的规范和标准,即 EJB 中的无状态会话 bean。 Spring 框架具有与原型“服务”类似的概念,可以将其应用于类以将它们标记为业务逻辑的外观。

      服务是一个组件,它封装了系统中的特定功能或行为。它在给定的对象模型(它自己的内部模型或系统中更通用的业务对象模型)上运行。如果您采用您的用例并创建与它们直接相关的服务,您就可以编写非常易于维护的软件。

      DCI Architecture 是对此的一种形式化,并试图做同样的事情,但同时试图通过向对象添加需要的行为来保持面向对象的真实性。

      【讨论】:

        【解决方案4】:

        我仍然感到困惑:“我是在告诉你做其他事情”还是“我在做别人要求我做的事情”?

        也许您所要做的就是玩芭比娃娃或 G.I. Joe 了解对象交互和职责所在。 GI乔受伤了(或者芭比弄断了一根钉子),所以他打电话给医生办公室。 “嘿,医生,我是乔,我需要预约。”所以你,孩子,告诉芭比去看医生,医生需要知道要打电话的医生以及如何打电话 - 一个参考和公共 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();
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-01-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-12-30
          • 2016-01-19
          相关资源
          最近更新 更多