# 12. 设计原则

# 12.1 间接原则——柔胜于刚,曲胜于直

	任何 计算机问题均可以通过增加一个间接(indirect)层来解决。
		Any problem in computer science can be solved with another layer of indirection. —— David Wheeler
		(对偶命题,任何社会问题均可以通过减少一个间接层类解决。)
		引用就是在值的基础上增加了间接层,由此给代码带来了极大的灵活性。
		其它如:文件系统中的路径、HTTP中的URI、数据库中的外键、程序中的变量等都具有间接指代作用
		广义地说,名字都具有间接性,因为名是实的代号,是实的引用,而不是实本身。
		从函数式编程看,具名函数也可以作为特殊的变量,代码也是一种数据,与通常的值和表达式一视同仁。
		从过程式编程看,函数与变量对应着某个特定的地址,C、C++、D等语言中的函数指针便是明证。
	幻数(magic number 或 magic constant)(硬编码问题)
		变量比幻数更能凸显编程者的意图,增强了代码的可读性。
		另一个优点是,如果多次出现,但拼写不一致,编译器会报错。
	函数和变量一样,是过程式编程中最基本的要素之一,二者的机理也同出一辙——都是提供了一种抽象机制和间接手段,分别把代码和表达式抽象化和简洁化。
		抽象的意义在于:掩盖了具体的细节,提供了代码的整洁度,赋予了明确的含义,提高了代码的清晰度。
		间接的意义在于:建立了名与实的映射,提高了代码的一致性和可维护性;
			实现了名与实的分离,提供了代码的灵活性和可扩展性。
	良好的标准是一些列规范的集合,而规范是显化的抽象。
		间接层和抽象层可以看做一个事物的两个方面:
			一种适当的中间层(泛指,非应用服务中间层概念),
在形式上表现为间接层,在实质上体现为抽象层。
				比如,出于安全原因,应用程序无权直接访问硬件,只能通过OS内核间接访问。
					作为硬件和应用程序的中介,内核提供了抽象的API接口,应用程序通过系统调用向其请求服务。
				JVM和CLR(通用语言运行平台(Common Language Runtime,简称CLR)是微软为他们的.Net虚拟机所选用的名称)之类虚拟机也是一样的,他们在操作系统之上提供了新的间接抽象层。
				区别在于,内核注重安全性和性能,JVM和CLR除此之外还有可移植性、开发效率、业界标准等其他的考量。
	多层架构也是运用间接原则的典范
		最著名的包括网络协议的OSI 7层模型,TCP/IP 4层模型和网络应用系统的 3层或N层架构。
		这类架构的特点是,
			每一层都有特定的职能,一面向上层提供服务,一面向下层寻求服务。
			下层不依赖于上层,上层只依赖于相邻的下层。
			(通常被称为封闭架构或不透明分层。如果上层能直接请求非相邻下层服务,则被称为开放式架构或透明分层。)
		MVC代表三个模块
			MVC架构或设计模式主要用于交互式系统,如基于GUI或web的前台应用。
		3层架构
			而最常见的3层架构是:表现层、业务层、数据层。(对比图P352)
				而3层架构则通常是高层的架构设计,多出现自企业级应用中。
			三层脚骨中的‘层’,如果指的是layer,则是对系统逻辑的划分,有助于提高软件的设计质量;
			如果指的是tier,则是对系统进一步的物理上的划分,即不同的层运行不同的服务器上,有助于提升软件的运行质量。
		与一般应用相比,企业级应用(enterprise application)通常包含专门领域的商业逻辑,系统的业务需求和应用环境更为复杂多变,常以多用户、大数据量、分布式、高集成、跨平台为特征,对软件质量的要求相应也更高。
			人们不仅需要保证包括可扩展(extensibility)、可维护性(maintainbility)、可重用性等在内的设计质量,更对包括安全性、可靠性、可伸缩性、性能、可获性(availability)、互用性(interoperability)等在内的运行质量有着严苛的要求。
		三层架构与MVC架构并不是对立的,后者尝尝嵌入前置的表现层。(P254)
	间接原则在封装中的体现
		(P355 图12-4间接原则在封装中的体现)
		类的公开接口即API担任了间接层的角色,成为外界和内部实现之间的联系桥梁。
		人们还能在客户类和服务类之间插入新的间接层——接口。
			该接口在编译器为实现类所继承,在运行期通过多态机制绑定实现类。
	间接原则在继承和多态中的体现
		封装带来接口与实现的分离,使得类的API成为间接层,从而完成数据抽象;
		继承和多态带来接口和实现的分离,使得类的超类型成为间接层,从而将数据抽象升级为多态抽象。
	间接、分离、抽象、规范,相生相依、互为因果,是为软件设计之本。
		它们充分体现了OOP三个基本特征的精髓,理所当然成为OOD(对象设计)的不二法门。
		引入具有间接功能的抽象模块,既能降低模块之间的相互依赖和影响度,又能使每个模块的职责更清晰、更专一。
			从而使整个系统更符合低耦合和高内聚的要求。
		不过也不能滥用,过多的间接层会以牺牲系统的简单性和时空性能为代价的,在实践中需权衡利弊。