栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

设计模式没那么玄

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

设计模式没那么玄

提要

模式的存在是为了解决复杂软件的应变性。而这一非功能性需求本身的潜台词就是,尽量别改动代码。如此,应对需求的变化手段就只剩下增量开发了。这是OCP的原则。
以结构型模式来说,一堆模式都在围绕着OCP原则打转。我们来逐步考查一下。

变量级别
int x = 3;
int y = 5;
int z = x + y;

在变量这个级别,顺序罗列语句/表达式,这是我们最基本的编码方式了,现在,如果要将z的求和算法,变为求均值呢?你可能这样改动书写:

int z = (x + y) / 2;

这样当然没问题,也看不出什么影响来。然而符合OCP的书写应该是:

int r = z/2;

即定义新得变量,对原有变量进行引用、包装。

函数级别
int calc(int x,int y){
	return x + y;
}

现在同样要改变计算的规则,变为求均值,修改既有函数实现吗?像这样:

int calc(int x,int y){
	return (x + y)/2;
}

要知道,这个既有函数可能具有高扇入性的,为了某一个客户端提出的需求而改动了它的实现,是极其危险得,你让其他客户端情何以堪?同样,正确的做法还是利用包装的思想:

int calcWrap(int x,int y){
	return calc(x,y)/2;
}

此时,没有破坏原有实现,并且至少有求均值需求的客户端,只需要改动一行代码便可以满意了。然而,我们习惯了OO,习惯了多态性,自然希望连客户端代码都不要动。这时函数级别就不能解决问题了(高阶函数、函数式编程另说);使用方法重载当然也不能解决问题,毕竟方法名虽然不变,函数签名也是变动了的。这也是为何Java代码动辄一堆类,甚至说是“面向类编程”的原因。我们来考察类级别的好处。

类级别
public interface Calc{
	int calc(int x,int y);
}

class CalcImpl implements Calc{
     int calc(int x,int y){
     	return x + y;
	}
}

class CalcProxy implements Calc{
	private CalcImpl calcImpl;
	// ...getter/setter
	int calc(int x, int y){
		return calcImpl.calc(x,y)/2;
	}
}

有经验的朋友看出来了,没错,就是简单的静态代理模式。利用接口特性的便利,父类对象指向子类实例的多态性,可以结合工厂模式等在运行时延迟、动态绑定实现,即保持了接口的一致性,使得客户端也可以只调用抽象API而无需再改动代码了。

上升到类级别,所谓的设计模式自然就出来了,你可以持有对抽象接口的引用,委托给具体实现类。对下层API调用并统一封装,提供外观类(门面模式);对上层接口又可继续进行转换适配(适配器模式)等。因此,在设计模式这种“术”的层面,你会发现代理模式、装饰器模式、适配器模式等结构型模式都很相像,实在没什么玄妙的。

我们从变量->函数->类级别的考察顺序,可以发现,OCP的原则——对修改关闭,对扩展开放,这种增量开发的思想核心就是包装。也就是OO三大特性之首的——封装。如果给OO三大特性继续排个高低辈分,我认为老大是封装。继承和多态性仍然是偏于技术层面得特性。而唯有封装,辨证得同时言明了独立性和扩展性之意,体现了面向对象得核心要义。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/936790.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号