设为首页 加入收藏

TOP

软件设计原则(一)
2017-10-13 10:40:09 】 浏览:7441
Tags:软件 设计 原则

基础原则

类与类之间主要有6种关系,他们分别是:依赖、关联、聚合、组合、继承(泛化)、实现。他们的耦合度依次增强。

依赖关系(dependence)假设A类的变化引起了B类的变化,则说名B类依赖于A类。对于两个相对独立的对象,当一个对象负责构造另一个对象的实例,或者依赖另一个对象的服务时,这两个对象之间主要体现为依赖关系。类A当中使用了类B,其中类B是作为类A的方法参数、方法中的局部变量、或者静态方法调用。大多数情况下,依赖关系体现在某个类的方法使用另一个类的对象作为参数。

依赖关系有如下三种情况:

1A类是B类中的(某个方法的)局部变量;

2A类是B类方法当中的一个参数;

3A类向B类发送消息,从而影响B类发生变化;

 

 

关联关系(association):两个相对独立彼此不受影响的类,一个类的实例与另一个类的一些特定实例存在固定的对应关系。它是一种结构化关系,用于表示一类对象与另一类对象之间有联系通常将一个类的对象作为另一个类的属性

单向关联:类A当中使用了类B,其中类B是作为类A的成员变量。

双向关联:类A当中使用了类B作为成员变量;同时类B中也使用了类A作为成员变量。

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

重数性关联: 重数性关联关系又称为多重性关联关系(Multiplicity):表示一个类的对象与另一个类的对象连接的个数。在UML中多重性关系可以直接在关联直线上增加一个数字表示与之对应的另一个类的对象的个数。

表示方式

多重性说明

1..1 或简写为  1

表示类的一个对象只与另一个类的一个对象有关联

0..*

表示类的一个对象与另一个类的零个或多个对象有关联;或只写 0 表示没有关联

1..*

表示类的一个对象与另一个类的一个或多个对象有关联

0..1

表示类的一个对象与另一个类的零个或一个对象有关联

m..n

表示类的一个对象与另一个类的最少m、最多n个对象有关联 (m<=n)

 

 聚合关系(aggregation):是关联关系的一种,耦合度强于关联,他们的代码表现是相同的,仅仅是在语义上有所区别:关联关系的对象间是相互独立的;而聚合关系的对象之间存在着包容关系,他们之间是“整体-部分”的相互关系,即has-a的关系,整体与部分可以分离的,可以具有各自的生命周期,部分可以脱离整体对象独立存在。

 

组合(composition):一种耦合度更强的关联关系,也称强聚合。表示“整体-部分”的关联关系,“整体”负责“部分”的生命周期,他们之间是共生共死的,整体的生命周期结束也就意味着部分的生命周期结束;并且“部分”单独存在时没有任何意义。

继承(泛化 generalization):表示类与类(或者接口与接口)之间的父子关系。

实现关系(Implementation):是用来规定接口和实线接口的类或者构建结构的关系,接口是操作的集合,而这些操作就用于规定类或者构建的一种服务。

表示一个类实现一个或多个接口的方法。接口定义好操作的集合,由实现类去完成接口的具体操作。

 

  • 抽象--核心思想是不变性的概念。去除不关心的属性,而强化重要的属性,帮助人们思考要做什么。
  • 封装--核心是分离关注点和信息隐藏,让程序借助最少的工作进行可靠的修改。
  • 模块化--核心思想是分而治之,各个模块应当高内聚、低耦合。
  • 层次结构--核心是对抽象的分级和排序,可以简化对系统的理解。

 软件设计原则:多聚合,少继承;低耦合,高内聚; 面向抽象编程;封装变化;实现重用(代码/算法重用)。

   低耦合:实现最简单的依赖关系,尽可能减少类/模块/层次/系统发生修改对其它类/模块/层次/系统造成影响,将影响范围简单化。比如实现单向依赖,实现抽象的耦合;

  高内聚:体现在以隔离为目标进行同一管理,一方面代表职责的统一管理,一方面体现了关系的有效隔离;

SOLID原则

单一职责原则(Single Responsibility Principle, SRP

核心思想:一个类只负责一个功能领域中的相应职责,应该只有一个引起它变化的原因。核心就是解耦和增强内聚性

一个类(大到模块,小到方法)承担的职责越多,它被复用的可能性就越小,而且一个类承担的职责过多,就相当于将这些职责耦合在一起,当其中一个职责变化时,可能会影响其他职责的运作,导致职责依赖;因此要将这些职责进行分离,将不同的职责封装在不同的类中,即将不同的变化原因封装在不同的类中,如果多个职责总是同时发生改变则可将它们封装在同一类中。单一职责,通常意味着单一的功能,因此不要为类实现过多的功能点,以保证只有一个引起它变化的原因;

通常以Facade模式和Proxy模式分离职责;

 

开闭原则(Open-Closed Principle, OCP)--对扩展开放,对修改关闭

个软件实体应当对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展(软件实体可以指一个软件模块、一个由多个类组成的局部结构或一个独立的类)。是SRP很好的补充。抽象编程是开闭原则的关键。是最重要的原则,里氏替换原则和合成/聚合复用原则为开放闭合原则的实现提供保证;

通过接口、抽象类等机制定义系统的抽象层,再通过具体类来进行扩展,让类依赖于固定的抽象,所以对修改是封闭的。如果需要修改系统的行为,无须对抽象层进行任何改动,只需要增加新的具体类覆写方法来实现新的业务功能即可,实现在不修改已有代码的基础上扩展系统的功能,达到开闭原则的要求。使得软件系统在拥有适应性和灵活性的同时具备较好的稳定性和延续性。

通常以Template Method 模式和Strategy模式实现;封装变化,是实现开放封闭原则的重要手段;

 

里氏代换原则(Liskov Substitution Principle,LSP)

子类可以扩展父类的功能,但不能改变父类原有的功能;是实现开闭原则的重要方式之一,在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象。

里氏代换原则核心思想:子类必须能够替换其基类,但基类不一定能够替换子类。

LSP 是继承复用的基石,只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而派生类也能够在基类的基础上增加新的行为。里氏代换原则是对开闭原则的补充。实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。

是关于继承机制的应用原则,是实现开闭原则的具体规范;

  • 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
  • 子类中可以增加自己特有的方法。
  • 当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
  • 当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。

 

接口隔离原则(Interface Segregation Princip

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇ASP.NET Zero--7.控制器加权限 下一篇ASP.NET Zero--6.菜单加权限

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目