下载本文示例代码
公孙龙,六国时辩士也。疾名实之散乱,因资材之所长,为“守白”之论。假物取譬,以“守白”辩,谓白马为非马也。 以马作为进行问题域进行建模,已知存在白马这种类型。显然存在马的超类,并且马类包含一个属性-颜色,是否需要建立白马的子类呢?显而易见的是,当马的颜色属性是白色时,马的一些实例表达了一个白马的特殊实例群(由此我们可以得知:白马显然是马),根据里氏替换原则,子类型必须能够替换掉它们的基类型,显然在分析了马的行为模式以后,我们可以得出结论:白马可以替换马。----!难道真的要建立白马、黑马、X马的子类吗? 我认为可以从以下几方面进行分析。 1、类的职责(很大程度上等同于服务能力,操作方式): 设计一个类,首先要从类职责的分析入手,一个类要承担响应的职责,反过来说同样的职责应该由同样的类承担,否则会造成类泛滥,实例孤单的状况。如果领域内马和白马承担同样的职责,应该只建立马一个类,不应该只见树不见林,造成不抽象的类的产生。 2、类的行为模式(当类承担响应职责时,如何扩展): 分析一个类要从类的行为模式入手,既然一个类要承担责任,其承担的责任表现方式是否一样呢呢?这就是她的行为模式,这也是里氏替换原则主要起作用的地方,如果两个类的职责相当,但行为模式不同则不能成为超类和子类的关系(比如"著名"的正方形不是长方形问题)。马类,作为超类,基于一些特殊的行为方式:吃草,跑...,对于白马她的行为模式和马是一样的,并没有不同,所以白马是马而非马的同根继承子类。对于长方形和正方形都是具有相同计算面积算法(职责)的四方形的子类。 -------以下是关于此事的一些扩展分析----------- 3、子类的产生: 何时需要产生子类呢:是对其父类的职责进行扩展,白马没有对父类的职责进行扩展,所以不是马的子类。首先子类要扩展超类,其次子类不能重写或废除超类的职责。 4、属性,状态的区别(类的域) 对于一些类,在状态不同时,会有不同的表现(状态机模式),所以,类的getter,setter的部分包含两种不同的特性,对于属于状态的部分,是我们要仔细分析的,而"白"马则属于属性类(非状态)的域, 一般来讲,一个类的实例要能提供相应的差异服务(由于状态不同)最好使用不变模式[生存周期状态不变]或状态机[生存周期有状态,但状态不由调用者控制]来实现。 5、抽象类和接口 由于java的单根继承特性,很多设计人员不敢定义抽象类为继承树根,一定要先定义马的接口,在建立抽象马,作为一种"准规范"无可厚非,但我认为这是不愿承担责任的表现,有行为的基类应该可以(必须?)从类定义开始,避免白马类(一旦马成为接口,白马的产生就更加"名正言顺"了)的出现.将来如果发生变化可以通过重构(导出接口和使用委托),解决问题。 6、对象的创建(组装)和使用应该分开 既然对象的状态如此重要,属性有有很大程度的不变性(白马在构造时就用该是白的,并且一生不变),而骑马的人不必要求马的属性(!),所以,我们应该将马的构造和使用分开,使领域模型更清晰。使用一些Ioc容器,比如Spring就能很好的解决这些问题。 7、分析问题的领域 说了这么多,有一个问题;如果有一个马的研究机构,专门对不同颜色的马进行专题研究,马的颜色可能会对马的行为有很大影响,例如战马如果是黄色(绿色,哈哈)更利于伪装,此时"白"可能是一个很关键的问题,颜色会影响到不同的伪装策略,此时将白马作为马的一个子类则是必须的!所以问题域不同,类的设计就不同,生活中的问题域比较清晰(生物学家和厨师对马的理解不同),而软件建模时往往问题域混杂,这也是OO设计时比较困难的问题,所以分析问题域也是非常重要的设计问题。
公孙龙,六国时辩士也。疾名实之散乱,因资材之所长,为“守白”之论。假物取譬,以“守白”辩,谓白马为非马也。 以马作为进行问题域进行建模,已知存在白马这种类型。显然存在马的超类,并且马类包含一个属性-颜色,是否需要建立白马的子类呢?显而易见的是,当马的颜色属性是白色时,马的一些实例表达了一个白马的特殊实例群(由此我们可以得知:白马显然是马),根据里氏替换原则,子类型必须能够替换掉它们的基类型,显然在分析了马的行为模式以后,我们可以得出结论:白马可以替换马。----!难道真的要建立白马、黑马、X马的子类吗? 我认为可以从以下几方面进行分析。 1、类的职责(很大程度上等同于服务能力,操作方式): 设计一个类,首先要从类职责的分析入手,一个类要承担响应的职责,反过来说同样的职责应该由同样的类承担,否则会造成类泛滥,实例孤单的状况。如果领域内马和白马承担同样的职责,应该只建立马一个类,不应该只见树不见林,造成不抽象的类的产生。 2、类的行为模式(当类承担响应职责时,如何扩展): 分析一个类要从类的行为模式入手,既然一个类要承担责任,其承担的责任表现方式是否一样呢呢?这就是她的行为模式,这也是里氏替换原则主要起作用的地方,如果两个类的职责相当,但行为模式不同则不能成为超类和子类的关系(比如"著名"的正方形不是长方形问题)。马类,作为超类,基于一些特殊的行为方式:吃草,跑...,对于白马她的行为模式和马是一样的,并没有不同,所以白马是马而非马的同根继承子类。对于长方形和正方形都是具有相同计算面积算法(职责)的四方形的子类。 -------以下是关于此事的一些扩展分析----------- 3、子类的产生: 何时需要产生子类呢:是对其父类的职责进行扩展,白马没有对父类的职责进行扩展,所以不是马的子类。首先子类要扩展超类,其次子类不能重写或废除超类的职责。 4、属性,状态的区别(类的域) 对于一些类,在状态不同时,会有不同的表现(状态机模式),所以,类的getter,setter的部分包含两种不同的特性,对于属于状态的部分,是我们要仔细分析的,而"白"马则属于属性类(非状态)的域, 一般来讲,一个类的实例要能提供相应的差异服务(由于状态不同)最好使用不变模式[生存周期状态不变]或状态机[生存周期有状态,但状态不由调用者控制]来实现。 5、抽象类和接口 由于java的单根继承特性,很多设计人员不敢定义抽象类为继承树根,一定要先定义马的接口,在建立抽象马,作为一种"准规范"无可厚非,但我认为这是不愿承担责任的表现,有行为的基类应该可以(必须?)从类定义开始,避免白马类(一旦马成为接口,白马的产生就更加"名正言顺"了)的出现.将来如果发生变化可以通过重构(导出接口和使用委托),解决问题。 6、对象的创建(组装)和使用应该分开 既然对象的状态如此重要,属性有有很大程度的不变性(白马在构造时就用该是白的,并且一生不变),而骑马的人不必要求马的属性(!),所以,我们应该将马的构造和使用分开,使领域模型更清晰。使用一些Ioc容器,比如Spring就能很好的解决这些问题。 7、分析问题的领域 说了这么多,有一个问题;如果有一个马的研究机构,专门对不同颜色的马进行专题研究,马的颜色可能会对马的行为有很大影响,例如战马如果是黄色(绿色,哈哈)更利于伪装,此时"白"可能是一个很关键的问题,颜色会影响到不同的伪装策略,此时将白马作为马的一个子类则是必须的!所以问题域不同,类的设计就不同,生活中的问题域比较清晰(生物学家和厨师对马的理解不同),而软件建模时往往问题域混杂,这也是OO设计时比较困难的问题,所以分析问题域也是非常重要的设计问题。
下载本文示例代码
“白马非马”论的面向对象分析“白马非马”论的面向对象分析“白马非马”论的面向对象分析“白马非马”论的面向对象分析“白马非马”论的面向对象分析“白马非马”论的面向对象分析“白马非马”论的面向对象分析“白马非马”论的面向对象分析“白马非马”论的面向对象分析“白马非马”论的面向对象分析“白马非马”论的面向对象分析“白马非马”论的面向对象分析“白马非马”论的面向对象分析“白马非马”论的面向对象分析“白马非马”论的面向对象分析
阅读(164) | 评论(0) | 转发(0) |