UnityUnity C#开发设计面向对象原则及类与类的关系

Posted xiaoyaoACi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UnityUnity C#开发设计面向对象原则及类与类的关系相关的知识,希望对你有一定的参考价值。

面向对象原则

1. 开闭原则
对扩展开放,对修改关闭,说白了就是写好的功能少改,不要把已有的功能改坏了。如果非要改,只有两种情况,第一种情况是原有代码确实存在问题。第二种情况是原有代码并没有问题,那么就需要对原有代码进行扩展(新增实现或子类重载)。

2. 类的单一职责
一个类有且只有一个改变它的原因。

3. 面向接口编程,而非面向实现
跟设计的过程是一致的,先确定要做什么,然后再写实现。

4. 优先使用组合而非继承
尽量用has a,避免使用is a。
三种情况:
第一种:假如A类和B类有关联,在A类中想做B类的事就用B类的对象或者直接调用静态方法即可。
第二种:假如A类和B类有相似的地方,那么只需要实现B类的接口或抽象方法即可。
第三种:确确实实AB是父子关系,这个时候再去用继承,并且保证子类只做父类没有的事情,而不是去改变父类做过的事情。如果一个子类需要去修改父类的操作,基本上就是父类设计的有问题了。

5. 依赖倒置
简单点说就是要面向接口编程,不要面向实现编程,因为接口是稳定的,实现是可变的。

6. 里氏替换原则
子类可以重写父类的功能,但是不能改变父类的功能。

7. 接口隔离
简单的说就是尽量不要把接口写的太臃肿,功能能拆分尽量拆分,不要什么方法都写到接口里,到时候实现这个接口的人会很累(因为他要实现那些他根本不需要用到的方法)。

8. 迪米特法则
不要跟陌生人说话,也不要太信任陌生人。
类与类交互时,传递的数据量越少越好,这样能够降低耦合度,免得其他类对你的数据做了你不知道的事。

类与类的关系

类关系强弱对比:依赖 < 关联 < 聚合 < 组合 < 实现 = 继承(泛化)

1、泛化Generalization(继承和被继承)

泛化表示一个更泛化的元素和一个更具体的元素之间的关系。继承关系,耦合度最高。
继承有两种: 1、泛化:子抽象父为泛化。
2、特化:父衍生子为特化。

2、实现Realization

类和接口的关系,表示类是接口所有特征和行为的实现。实现其实等于变相的继承,其耦合度跟泛化基本相同。

3、关联Association

类之间的联系,如客户和订单、汽车和轮胎、公司和员工。

  1. 关联是一种结构化关系,用于表示一类对象与另一类对象之间有联系,使一个类知道另一个类的属性和方法。
  2. 这种关系比依赖更强、不存在依赖关系的偶然性、关系也不是临时性的,一般是长期性的。
  3. 关联可以是单向的,也可以是双向的。双向的关联可以有两个箭头或者没有箭头,单向的关联有一个箭头。
  4. 在面向对象语言中,关联关系是通过使用成员变量来实现的,即在一个类中指定另一个类的对象为本类的成员变量。

关联是类与类之间最常用的关系,从关联的方向和数量角度上来划分,关联主要分为四类:
1.双向关联
从面向对象的角度来看,正常的关联关系都应该是双向的,比如学校和老师。从UML的角度来看双向关联又分为有箭头和无箭头两个版本:
无箭头版本:unspecified association to unspecified association(未指定关联到未指定关联),连接两个都未指明的实体关系。

有箭头版本:navigable association to navigable association(导向性关联到导向性关联),引用实体与引用实体之间的关联关系,而两者都可以互相访问。

2. 单项关联:
一个类中引用另外一个类的对象作为成员变量的关系就叫单项关联,比如客户和地址、工人和工具。单项关联又分为两种情况,一种是被引用方可以访问引用方,另一种是被访问方不可以访问引用方。

无X的版本:unspecified association to navigable association(未指定关联到导向性关联) 未指明的实体关联引用实体(可访问的实体)

有X的版本:Non-navigable association to navigable association(未导向性关联到导向性关联) 非引用实体关联引用实体,前一个类单向知道后一个类的存在(后一个类不知道前一个类的存在)。

同样的两个类,在不同系统上设计的方式可能有所不同,比如如果是个游戏主页,地址对于客户来说并不那么重要,这时候地址没有必要反向了解用户的信息。但如果是个电商平台,就有可能要根据地址来给客户做自画像,这个时候地址就需要拥有访问客户的权限。这跟双向关联又有所不同,双向关联(有箭头版本)的双方是必须互相了解对方的,而单项关联只是要求被关联者拥有访问关联者的权限,并不一定或者并不经常需要访问关联者。

3. 自关联:
在系统中可能会存在一些类的属性对象类型为该类本身,这种特殊的关联关系称为自关联。

4. 多重性关联Multiplicity:
多重性关联就是我们常说的一对多、多对多,通常有以下几种情况:

表示方式描述
1…1或者1就一个,表示另一个类的一个对象只与一个该类对象有关系
0…10个或1个,表示另一个类的一个对象没有或只与一个该类对象有关系
0…*0个或多个,表示另一个类的一个对象与零个或多个该类对象有关系
1…*一个或多个,表示另一个类的一个对象与一个或多个该类对象有关系
m…n表示另一个类的一个对象与最少m、最多n个该类对象有关系 (m<=n)

下图表示一个班级可以有0到*个学生(星号也可以为1)。

关联关系中有两种特别的关系,一个是聚合关系,一个是组合关系(也叫合成关系):
1. 聚合关系(Aggregation)

  • 聚合关系是关联关系的一种,是强的关联关系。
  • 聚合关系表示的是整体和部分的关系,即has-a的关系,整体与部分可以分开。
  • 整体与个体可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享。
  • 聚合关系也是通过成员变量来实现的。但是,关联关系所涉及的两个类处在同一个层次上,而聚合关系中,两个类处于不同的层次上,一个代表整体,一个代表部分。
  • 关联与聚合仅仅从语法上是无法分辨的,必须考察所涉及的类之间的逻辑关系。
  • 例如汽车由引擎、轮胎以及其它零件组成,公司与员工,大雁群与大雁,都是聚合关系。
    聚合关系的UML图使用空心菱形作为起始端,末尾端可以是直线也可以是箭头:
  • 直线代表被聚合端不允许访问聚合端。
  • 箭头代表被聚合端可以访问聚合端。

    2. 组合关系(Composition)
  • 组合关系是关联关系的一种,是比聚合关系还要强的关系。
  • 组合关系也是整体与部分的关系,但是整体与部分不可以分开。
  • 它要求普通的聚合关系中代表整体的对象负责代表部分的对象的生命周期。
  • 比如大雁和翅膀,人和头,公司和部门都是组合关系。
    组合关系的UML图使用实心菱形作为起始端,末尾端可以是直线也可以是箭头:
  • 直线代表部分端不允许访问主体端。
  • 箭头代表部分端可以访问主体端。

4、依赖Dependency

是一种使用的关系,即一个类的实现需要另一个类的协助。另一个类型作为当前类型的方法的参数或返回值类型出现。依赖关系在面向对象语言中体现为局部变量、方法的参数或者对静态方法的调用。依赖是单向的,由依赖方指向被依赖方,也就是使用方指定被使用方。
比如类ClassA依赖类ClassB:

通常情况下依赖会表现为以下几种情况:

  1. A类方法当中的一个参数使用B类;
  2. A类某个方法中的局部变量使用B类;
  3. A类向B类发送消息,从而影响B类发生变化;
class ClassB
{
	public void func0()
	{
	}
	public static void statFunc()
	{
	}
}
// 情况1:A类方法当中的一个参数使用B类
class ClassA
{ 
	public void func0(ClassB classB)
	{
	}
}
// 情况2:A类某个方法中的局部变量使用B类
class ClassA
{ 
	public void func0()
	{
		ClassB b = new ClassB();
		b.func0();
	}
}
// 情况3:A类向B类发送消息,从而影响B类发生变化
class ClassA
{ 
	public void func0()
	{
		ClassB.statFunc();
	}
}

UML中将依赖关系分为四种:使用依赖Usage、抽象依赖Abstraction、授权依赖Permission、绑定依赖Binding
一、 使用依赖Usage:
一个类使用了另一个类,以实现它的行为,具体依赖形式:
调用call:一个类调用其他类的方法。
参数parameter:一个类的方法使用其他类作为参数。
发送send:声明信号发送者和信号接收者之间的关系。
实例化instantiate:一个类的方法中创建了另一个类的实例。

二、 抽象依赖Abstraction:
表示客户与提供者之间的关系,客户与提供者属于不同的抽象事物,具体依赖形式:
跟踪trace:声明不同模型中的元素之间存在一些连接但不如映射精确。
精化refine:声明具有两个不同语义层次上的元素之间的映射。
派生derive:声明一个实例可以从另一个实例导出。

三、 授权依赖Permission:
表达一个事物访问另一个事物的能力,具体依赖形式:
访问access:允许一个包访问另一个包的内容。
导入import:允许一个包访问另一个包的内容并为被访问包的组成部分增加别名。
友元friend:允许一个元素访问另一个元素,不管被访问的元素是否具有可见性。

四、 绑定依赖Binding:
绑定依赖属于较高级的依赖类型,用绑定模板以创建新的模型元素。具体依赖形式:
绑定bind:为模板参数指定值,以生成一个新的模型元素。比如泛型。

类与类的关系总结

引用一张图总结一下各种关系:

以上是关于UnityUnity C#开发设计面向对象原则及类与类的关系的主要内容,如果未能解决你的问题,请参考以下文章

6.17 面向对象思想及类的提纲

面向对象设计的基本原则都有哪些

C# 实例解释面向对象编程中的依赖反转原则

C# 实例解释面向对象编程中的单一功能原则

C# 实例解释面向对象编程中的接口隔离原则

C# 实例解释面向对象编程中的开闭原则