系统复杂性
软件系统来源与真实世界的需求,由于现实世界系统的复杂,导致了软件系统的复杂性,其复杂性常常超出了人类认知的范围,虽然我们不能消除这些复杂性,但是我们可以通过一些方法(抽象 ,分解,分层)来掌握这些复杂性。
复杂的事物也有着自己本身的特点:系统是分层的 从外到内层(part of)、从上到下层(is a)、通过分层后,我们可以找到系统的基本组成部分,不同的人分层的标准不一样,导致我们看到的基本组成部分不一样。
系统分解后,组件内的联系通常比组件间的联系更强。这一事实将组件中的高频动作(涉及组件内部结构)和低频动作(组件间相互作用)分离开来。我们可以先关注各个组成部分外部表现形式,忽略内部细节,从它提供的功能来认识它。因为所有内部的实现都是为了承诺外部的功能。这也叫做抽象的思维方式,是认知复杂事物一种通用的方法,抓到事物的主要点,忽略次要点,细节。屏蔽复杂的细节,能够让我们更容易理解他们。也只有忽略细节,我们才能认知复杂的事物,因为人处理信息的能力有限,这也要求我们必须要舍弃 细节、次要的,非本质的信息。再依据28原则,事物的核心主要集中在系统的少数部分。反过来理解,我们在设计或者创建新的事物是,也是由简单(核心的、抽象的)到复杂(实现)进行的。造物主也是一样的。我们构造(设计)的时候,就需要 低耦合,高内聚,面向接口设计。
复杂系统,同一个系统内部,不同系统之间 都会有相同或者相似的地方,我们需要分析认识到这些共性,了解了其中一个,也就知道了其他。有了共性,就能复用,复用也是一种很重要的认识复杂事物的手段。
复杂系统通常都是通过稳定的中间件形式来构建,只有系统中各个子系统稳定了,整个系统才会稳定。我们可以利用稳定的中间形式构建更为复杂的系统。类比到代码设计上面,我们需要分析出,哪些是稳定的部分,哪些是可以扩展和修改的部分。稳定的部分就不要改动,否则,将会产生严重的影响。与开闭原则有相同的地方。
面向对象面
向对象既可以用来解决复杂系统的认识,也可以用来指导复杂系统的设计。面向对象分析和设计的主要方法为:抽象,封装、继承(多态)。
1、抽象 可以屏蔽复杂事物的细节,抓住事物的本质,简化认知事物的复杂度。
2、封装 可以 分离关注,将内部与外部分开。以局部自治的方式提供契约责任。将组件间影响程度降低到最低。
3、继承 主要是为了解决复用,共性问题。是定义系统层次结构的一种方法。
设计原则
设计原则指导怎么设计复杂系统
高内聚,低耦合与抽象
高内聚:每个类里面属性都是和行为强相关的,不会有其他不相关的属性。每个行为都是操作自己的属性。
低耦合:每个类只依赖和自己直接相关的类。不依赖多余的类或者间接相关的类,尽量依赖接口而不是实现,
1、 迪米特法则:又叫最小知识(最少依赖)原则,每个模块只应该了解和它关系密切的模块的有限知识。反过来理解,我们设计模块或者类的时候,我们需要提供最小接口(基于最小接口而非最大实现编程),这样其他类使用起来才会更方法。尽量内聚,减少外部协调。自己能干的事情,就不找别人。
2、依赖反转原则: 实现应该依赖抽象,抽象不应该依赖实现,面向接口而不是实现
3、接口隔离原则 :客户端不应该强迫依赖它不需要的接口,如果满足单一职责原则,接口隔离就更容易实现。
4、单一职责原则(Single Responsibility Principle):每个类模块职责单一,每个类提供的功能应该为该类最小承诺
共性和复用
里式替换原则: 子类能够替换所有父类出现的地方。共性与复用,可以测试类设计是否应该使用继承的关系。
稳定和扩展
开闭原则(Open Closed Principle) :对扩展开放,对修改关闭,需要在分析需求是,确定哪些是稳定的,哪些是可扩展的。找出稳定的中间部分。稳定的部分一般是底层的,框架性的,与业务无关的。
设计模式
创建
将对象的创建和使用分开,因为对象的创建过程有可能和复杂。
1、单例
2、工厂(抽象工厂)
3、建造者
4、原型
结构
主要是解决类结构的层次问题,是组成还是继承。
1、代理 (继承)
2、桥接,组合 (灵活,降低类层次关系的复杂度)
3、装饰器,继承+组合
4、适配器,类适配(继承),对象适配(组合)
5、门面(组合,封装)
6、组合模式,处理树形结构数据(区别与 继承、组合,继承模式更有效)
7、享元模式,共享、缓存
行为
主要是解决类(模块)与类(模块)之间通信问题。请求方->消息->接受方
1、观察者
2、模板
3、策略
4、责任链
5、状态模式
6、迭代器模式
7、备忘录模式
8、命令模式
9、解释器模式
10、中介模式
总结
1、以稳定部分来构建最小系统。
2、抽象出共性(属性,行为)。复用,通常是以由下往上,由细节到共性。
3、子系统之间需要 高内聚和低耦合
4、设计分析需要迭代循环演进,比如一个类代码太多,类太大,需要拆分。类的结构层次随着迭代也可能调整
5、代码实现上面需要面向接口编程和提供代码的可复用性,可扩展性,可维护性
网友评论