00 面向对象与 UML 类图

2019年10月17日15:27:22 By ddhhdd

预计阅读时间:12 分钟

1 活字印刷,面向对象

话说三国时期,曹操带领百万大军攻打东吴,大军在长江赤壁驻扎,军船连成一片,眼看就要灭掉东吴,统一天下,曹操大悦,于是大宴众文武,在酒席间,曹操诗兴大发,不觉吟道:“喝酒唱歌,人生真爽。”众文武齐呼:“丞相好诗!”于是一臣子速命印刷工匠刻版印刷,以便流传天下。

样张出来给曹操一看,曹操感觉不妥,说道:“喝与唱,此话过俗,应改为‘对酒当歌’较好!”于是此臣就命工匠重新刻版。工匠眼看连夜刻版之功,彻底白费,心中叫苦不迭,只得照办。

样张再次出来请曹操过目,曹操细细一品,觉得还是不好,说“人生真爽”太过于直接,应改问语才够意境,因此应改为“对酒当歌,人生几何?”当臣转告工匠之时,工匠晕倒...

“小菜你说,这里面问题出在哪里?”大鸟问到。

小菜说:“是不是因为三国时期活字印刷还未发明,所以要改字的时候,就必须整个刻版全部要重刻。”

大鸟:“说得好!如果是有了活字印刷,则只需要更改四个字就可,其余工作都未白做。岂不妙哉。”

第一,要改,只需更改要改之字,此为可维护

第二,这些字并非用完这次就无用,完全可以在后来的印刷中重复使用,此乃可复用

第三,此诗若要加字,只需另刻字加入即可,这是可扩展

第四,字的排列其实可能是竖排可能是横排,此时只需将活字移动就可以满足排列需求,此是灵活性好

而在活字印刷术出现之前,上面的四种特性都无法满足,要修改,必须重刻,要加字,必须重刻,要重新排列,必须重刻,印刷完这本书后,此版已无任何可再利用价值。

2 面向对象的好处

大鸟:“哈,这下你明白了?我以前也不懂,不过做了软件开发几年后,经历了太多类似曹操这样的客户要改变需求,更改最初想法的事件,才逐渐明白当中的道理。其实客观的说,客户的要求也并不过分,不就是改几个字吗,但面对已完成的程序代码,却是需要几乎重头写过的尴尬,这实在是痛苦不堪。说白了,原因就是因为我们原先所写的程序,不容易维护,灵活性差,不容易扩展,更谈不上复用,因此面对需求变化,加班加点,对程序动大手术的那种无奈也就成了非常正常的事了。之后当我学习了面向对象的分析设计编程思想,开始考虑通过封装、继承、多态把程序的耦合度降低,传统印刷术的问题就在于所有的字都刻在同一版面上造成耦合度太高所致,开始用设计模式使得程序更加的灵活,容易修改,并且易于复用。体会到面向对象带来的好处,那种感觉应该就如同是一中国酒鬼第一次喝到了茅台,怎个爽字了得呀!”

3 UML 类图

3.1 类

大鸟:“首先你看那个‘动物’矩形框,它就代表一个(class)。类图分为三层,第一层显示类的名称,如果是抽象类,则就用斜体显示;第二层是类的特性,通常就是字段和属性;第三层是类的操作,通常是方法或行为。注意前面的符号+表示 public,-表示 private,#表示 protected。

3.2 接口

大鸟:“然后注意到左下角的‘飞翔’,它表示一个接口图,与类图的区别主要是顶端有<<interface>>显示。第一行是接口名称,第二行是接口方法。接口还有另一种表示方法,俗称棒棒糖表示法,就是唐老鸭实现了‘讲人话’的接口。”

小菜:“为什么要是‘讲人话’?”

大鸟:“鸭子本来也有语言,只不过只有唐老鸭是能讲人话的鸭子。”

小菜:“有道理。”

3.3 继承

大鸟:“接下来就可讲类与类,类与接口之间的关系了。你可首先注意动物、鸟、唐老鸭之间的关系符号。”

小菜:“明白了,它们都是继承的关系,继承关系空心三角形 + 实线来表示。”

范例2:

public class Person {
    ......
}
public class Student extends Person {
    ......
}

3.4 实现接口

大鸟:“我举的几种鸟中,大雁是最能飞的,我让它实现了飞翔接口。实现接口空心三角形 + 虚线来表示。”

范例2:

public interface Vehicle{
    public void move();
}
public class Ship implements Vehicle{
    @Override
    public void move() {
        .......
    }
}

3.5 关联

大鸟:“你看企鹅和气候两个类,企鹅是很特别的鸟,会游不会飞。更重要的是,它与气候有很大的关联。我们不去讨论为什么北极没有企鹅,为什么它们要长年跋涉。总之,企鹅需要知道‘气候’的变化,需要‘了解’气候规律。当一个类‘知道’另一个类时,可以用关联(Association)。关联关系实线箭头来表示。”

范例2:

public class Customer {
    private Address address;
   ......
}
public class Address {
   ......
}

3.6 聚合

大鸟:“我们再来看大雁与雁群这两个类,大雁是群居动物,每只都属于一个雁群,一个雁群可以有多只大雁。所以它们之间就满足聚合(Aggregation)关系。聚合表示一种弱的‘拥有’关系,体现的是 A 对象可以包含 B 对象,但 B 对象不是 A 对象的一部分聚合关系空心的菱形 + 实线箭头来表示。”

范例2:

public class Car {
    private Engine engine;

    public Car(Engine engine) {
        this.engine = engine;
    }

    public void setEngine(Engine engine) {
        this.engine = engine;
    }
}
......
public class Engine {
   ......
}

3.7 组合

大鸟:“合成(Composition,或翻译成‘组合’)是一种强的‘拥有’关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样。在这里鸟和其翅膀就是组合的关系,因为它们是部分和整体的关系,并且翅膀和鸟的生命是周期相同的。组合实心的菱形 + 实线箭头来表示。另外,你会注意到组合关系的连线两端还有一个数字‘1’和数字‘2’,这被称为基数。表明这一端的类可以有几个实例,很显然,一个鸟应该有两只翅膀。如果一个类可能有无数个实例,则就用‘n’来表示。关联关系、聚合关系也可以有基数的。”

范例2:

public class Head {
    private Mouth mouth;

    public Head() {
        mouth = new Mouth();
    }
}
......
public class Mouth {
    ......
}

注意:new Mouth()是写在构造方法里面的;如果写在普通的方法里面,那就是依赖关系了。

3.8 依赖

大鸟:“动物有几大特征,比如有新陈代谢,能繁殖。而动物要有生命力,需要氧气、水以及食物等。也就是说,动物依赖于氧气和水。它们之间是依赖关系(Dependency),用虚线箭头来表示。”

范例2:

public class Driver {
    public void driver(Car car) {
        car.move();
    }
    ......
}
public class Car {
    public void move();
    ......
}

小菜:“啊,看来 UML 类图也不算难呀。”

大鸟:“吼吼,记住哦,编程是一门技术,更加是一门艺术,不能只满足于写完代码运行结果正确就完事,时常考虑如何让代码更加简练,更加容易维护,容易扩展和复用,只有这样才可以真正得到提高。写出优雅的代码真的是一种很爽的事情。UML 类图也不是一学就会的,需要有一个慢慢熟练的过程。所谓学无止境,其实这才是理解面向对象的开始呢。”

本文内容摘抄于《大话设计模式》

posted @ 2020-08-07 07:49  ddhhdd  阅读(44)  评论(0)    收藏  举报