C#之设计模式中UML类图四种关系的代码体现

时间:2021-04-03 19:13:26

    在《大话设计模式》的学习过程中,起初对于每个模式的类图不是很在意,通过代码去理解模式的含义,经历了向别人请教的阶段之后,才发现UML类图在设计模式中重要的地位,即代码中类与类之间的关系往往在UML类图中已经定义好,于是有必要对四种常见关系在代码中如何体现做下总结。

    首先对四种关系进行回顾:

    一、依赖

    二、实现

    三、泛化

    四、关联

    对于UML的四种关系已经在博客http://blog.csdn.net/zzh920625/article/details/42610873中进行了总结,在此主要结合C#和设计模式重新对其进行分析。


依赖关系

   首先是依赖关系,依赖关系是五种关系中耦合最小的一种关系,通过查资料,在C#中不建议双向依赖,仅仅是单向依赖,比如类A要完成某功能需要B,则类A依赖类B。举个例子,每天回家、上课都需要超哥骑车载着我(在这里表达下感激之情),我和超哥的关系就是依赖关系。假设有两个类,一个类ZZH是全国叫“张振华”的人组成的,另一个类MSC是全国叫“马世超”的人组成的。

                         C#之设计模式中UML类图四种关系的代码体现

    就像上面这个图一样,如果ZZH类要依赖MSC类的话,通过查阅资料,有三种方法:

   (1)MSC是Public的,由ZZH直接调用。

Class ZZH
{
Public ZZH()
{
}
}
//在类中直接调用即可。
Class MSC()
{
Public MSC()
{
}
}

   (2)MSC类这个类充当ZZH类的某个方法中的一个变量

    比如:

class  ZZH()
{
Public void huijia()
{
MSC msc =new MSC() //成为ZZH方法中的一个变量;
}
}

   (3)MSC类是ZZH类中某个方法需要传递的一个参数。 

    比如:

 class  ZZH()
{
Public void huijia(MSC msc)
{
//马世超骑车载着张振华回家。
}
}

   总的来说,类与类之间的依赖关系,就是1、public直接调用;2、用在方法中,用作变量、参数或者返回值。That’s All.依赖关系是最浅的一种关系,在代码中的用出也很常见,掌握好这三种形式就OK了。

继承和实现

   如果说接口是一种特殊的类的话,那么实现接口的过程也可以看做是一种继承,或者将其统称为泛化,个人总结二者在代码的实现上如出一辙。

   先上图:

                           C#之设计模式中UML类图四种关系的代码体现

    

    通过对《大话设计模式》中二者关系的总结,继承和实现通过“:”来联系。

    比如:     
 Interface  InterfaceA
{
Void HuiJia(Vehicle vehicle);
Void ShangXue(Vehicle vehicle);
}

Class B:InterfaceA
{
Private bicycle =new Vehicle();
Private car=new Vehicle(); //实例化两种交通工具的变量
Public void HuiJia(Vehicle bicycle)
{
//回家的时候还是和超哥骑自行车;
}
Public void ShangXue(Vehicle car)
{
//上学的时候和超哥开汽车来。
}
}

    这就是类和接口之间的实现关系在代码上的体现,同理继承也是如此,“:”前面和后面分别是派生类和基类。

对于这两个关系的代码实现由于自己的代码量还不是很大,如果大家有其他的方法,希望多多交流。

关联

    关联,个人认为是在四种关系关系最为错综复杂的一种了,关联包含:

    1、普通关联(单向、双向),2、聚合,3、组合

    首先,组成关联关系的两个类肯定是同一级别的,比如“人”和“自行车”他们是关联关系,但不是组合或者聚合,因为自行车不属于人的一部分。

    关于关联关系在代码上的实现,请看例子:

                        C#之设计模式中UML类图四种关系的代码体现

    学校和学生之家是关联关系:

 public class School
{
private Student student;
public Studetn msc() // Student实例化做变量
{
//我和超哥骑车去上课
}
public void KaoShi(Studetn zzh) //student对象做参数
{
//我和超哥参加考试
}
}

    从这个例子中可以看出,这完全就和“依赖关系”的代码一样,我觉得想要了解二者不同,可以参考这个资料:

· 从类的属性是否增加的角度看:

   发生依赖关系的两个类都不会增加属性。其中的一个类作为另一个类的方法的参数或者返回值,或者是某个方法的变量而已。

   发生关联关系的两个类,其中的一个类成为另一个类的属性,而属性是一种更为紧密的耦合,更为长久的持有关系。

·  从关系的生命周期来看:

   依赖关系是仅当类的方法被调用时而产生,伴随着方法的结束而结束了。

关联关系是当类实例化的时候即产生,当类销毁的时候,关系结束。相比依赖讲,关联关系的生存期更长。

    而对于组合关系和聚合关系,由“has-a”与“is a kind of ”可以看出,组合的关联性要比聚合更强一点,如果体现在代码上就是耦合性更强一点,在《大话设计模式中》可以看到,关于聚合关系,客户端可以同时访问两个类,代码的体现和普通关联差不对,两个类的耦合性相对较弱,而对于组合关联,是通过访问“整体”的类来运行的,不可以直接访问“a kind of ”的那个类,耦合性特别强,而且他们的生命周期是同步的。

    举例:比如有两个类,一个是人类,一个是肢体类。  

Class ZhiTi()
{
Public void yundong()
}
Class Person()
{
Public ZhiTi a
Public Person()
{
ZhiTi myleg=new ZhiTi();
}
}

   有的时候会发现,其实聚合和组合的代码都特别像,那就需要从定义、用法上来进行区分,何时何地使用何种关系,清楚了之后,用就OK了。

总结

    这一块其实自己也不太明白,也是前段时间敲《大话设计模式》的时候发现的问题,通过查资料解决了一些问题,就贴出一篇博客,但是具体四种关系究竟该如何把握,现在还是做得不好,我想通过不断的总结,不断的去实践慢慢的总会做得越来越好的。也希望如果大家在这块问题上有好的见解能和我交流。

    Finally, HappyNew Year 2015!