参考资料:
《设计模式——可复用面向对象软件的基础》
《Object Design: Roles, Responsibilities, and Collaborations》
http://en.wikipedia.org/wiki/Extensibility
从我理解,在软件范畴上,是软件系统本身的属性,或者进一步说是设计的属性,代码的属性。因为我们经常说设计的可扩展性,代码的可扩展性。那与之相对应的是什么呢?是变化,软件环境的变化(可能是业务环境,运行环境)导致软件要进行改动才能满足人们对它的要求,这种系统本身适应变化的能力就是可扩展性。
首先让我们来看看目前系统被扩展的几种形式:
1)直接修改代码。
相信大家都有过这样的经历,当需求改变或者增加新需求的时候。我们可能会修改多个类文件,可能还涉及配置文件,前台页面文件。这种改动,肯定要引起重新编译,打包和部署,肯定是需要停机的。这种改动涉及的面积广,需要预先经过很细致的分析,改完之后需要面积很大的回归测试以保证修改不会引入新的问题。
2)直接修改代码,但只局限在一个类或方法中。
这种虽然也是直接修改代码,但改动的范围受到了限制,对系统其它部分的影响也不是那么大了,分析起来相对容易。需要进行回归测试的范围也比上面的做法小。依然需要重新编译,打包和部署。
3)利用继承,编写子类继承以后的类,在子类里添加新的业务逻辑。
这种做法,没有修改以前的任何业务逻辑代码,而是增加了新的类来容纳新的业务逻辑。但是,在将新的类链接到代码中,同样需要改动部分代码。比如对新类的实例化过程是需要静态编译链接的。
ClassA{
void doSomething();
}
......
ClassA a = new ClassA();
......
ClassB extends ClassA{
void doSomething();
void addedMethod();
}
......
ClassA a = new ClassB();
......
有人说用工厂方法,简单工厂不行,FactoryMethod也不行,都达不到消除实例化新类的代码。
4)运行时对象装配。
接下来,大家可能想到了,那就是将类的实例化逻辑移到运行时,通过反射,来进行装配,这确实解决了第3)种问题。Spring目前做的主要就是这些事情。到这个时候才真正满足开闭原则。
Spring给我们提供了一个非常灵活扩展的基础技术架构。关于这个,可以看看Martin Fowler关于依赖注入
的文章。
5)基于模块的运行时动态扩展。
到现在为止,我们讨论的都是比较细粒度的在技术上的扩展。想象一下,如果增加一些功能,就去继承各种各样的类,然后经过复杂的装配过程,才能完成一个功能的添加和改进。即使你新增加了类,改动了Spring的配置文件,实现新的装配,但仍然有一点,你需要编译整个项目。也就是说,前四种都没有达到模块级别的扩展。
OSGi给出了解决方案,可以实现模块级别的动态扩展,而且是运行时的。所谓运行时模块的动态扩展,比如说你需要增加一些新的功能,你可以将新开发的类和文件按照Bundle进行组织,然后直接扔到运行时环境下,这些功能就可以用了。
Eclipse的插件体系结构就是以equinox(一个OSGi规范的实现)为核心构建的。它里面提到了扩展/扩展点的概念,这是一个远比前面四种解决方案更灵活的解决方案,而且与4)相比,实现了关注点的分离。举个例子:
比如说我开发了一个上传文件的功能,上传文件类型和上传的地址可以动态进行扩展。
Spring处理方式: 在bean配置里灵活配置上传类型和上传地址,每增加一个地址或文件类型,都要对该配置文件进行修改。更可怕的是,张三开发了这个文件上传模块,开发别的模块的李四如果要用这个功能,需要和张三沟通,要么自己去改配置文件,要么要请求张三添加自己的文件上传路径。当系统规模增大,改动次数增加,这种复杂性几乎是不能管理的,需要非常大的成本。
Eclipse的实现方式:张三开发了一个文件上传插件,里面暴露出两个扩展点,一个是文件类型,一个是文件上传地址。
李四甚至不用和张三打招呼,自行开发两个扩展,并注册到扩展点上。张三在运行时收集扩展,进行处理。实现了功能使用和功能定义的关注点分离。大家只要遵守扩展的契约就行了。
6)基于中间语言。
框架通常定义了一些Hotspot(热点),在这些点上,可以进行扩展。平台,可扩展性是最强的,比如window 平台,你可以开发应用程序运行在上面。windows提供了几千个API,你可以使用他们来开发应用程序。我们在看看Firefox,他可以从主题,插件,扩展来扩充。我们常接触的扩展,也叫Extension可以通过XUL,XBL,Javascript,CSS来进行开发。从思路上看,他和windows的做法是一样的,都是通过中间的某种特殊的语言来进行扩展,只不过Windows支持的语言更多一点罢了。由此推断,从技术上来说,要获得最大的可扩展性,就要通过一种或多种中间语言来进行扩展。比如现在流行的OpenSocial API和Facebook都是这个思路。这样说来,DSL的出现就是顺理成章的了,它是为了满足在某个业务领域的扩展而设计的。思路还是和前面说的一样。 说白了,就是顺序,选择和循环可以表达所有逻辑,这是证明过的,这是语言能够带来灵活性的本质。
到目前为止,从技术层面讲,这应该是最灵活的方式了。但是,模块如何划分呢?大还是小?之间的依赖如何进行控制?为什么要定义这个扩展点?
这就引出另外一个问题,“我们为什么而扩展?”
扩展是要有目的性的,我们不能盲目为了扩展而扩展,把系统搞得极其复杂,来应对几乎不可能发生的变化。说道这里,又谈到设计。传统软件开发过程讲究Big
Front
Design,就是大量的前期设计。XP的一个实践是简单设计,我比较推崇简单设计,就是刚刚好的设计。不多也不少,就像五花肉,肥而不腻。如何做到这
些,只能依赖于设计者本身的经验了。
回答这个问题,重要的是我们看的多远,能够预测到多少可能的变化。这些都是基础。还有一个就是你对上下文的了解程度,这个需要知识的补充。上下文知识越丰
富,对其中的联系就越清楚,那也就越能识别出系统可能的变化。而我们设计系统时,就可以为这些变化,准备一些Slot,设计一些扩展点。可扩展性是设计出来的。
如何把握这个分寸,确切的说,我也不知道,Context-special。
总结一下:
1)为了控制复杂性,系统必须在逻辑上进行划分,各个逻辑块之间应该是松散耦合,需要对领域的理解和仔细分析。
2)可扩展性不是一蹴而就的,是需要随着你对业务领域理解的深入而不断重构获得。一般三次可以达到比较理想的程度。
3)在系统演化过程中,时刻准备着,保持对复杂性的关注。确保这些复杂性得到消化。
4)要想获得可扩展性,你需要看得远一点,对上下文做充分的了解。
人无远虑,必有近忧。
系统也一样。
分享到:
相关推荐
JMP Extensibility Synergy with MATLAB JMP 可扩展性与 MATLAB 的协同作用.pdf
Pro ASP.NET Extensibility
使用Managed Extensibility Framework方便的扩展应用程序
The API includes extensibility points that enable third parties to author custom cache implementations and make them available through a common set of APIs. Additionally the tentative plan is to ...
Visual Studio 扩展性示例 这些示例演示了如何自定义 Visual Studio IDE 和编辑器的外观和行为。 以下是扩展 Visual Studio 的一些方法...其他可扩展性示例 如果要为部署为 NuGet 包的 UWP 构建 XAML 控件,则可以添加
Neos UI的可扩展性示例 请参阅“资源/专用”和Configuration / Settings.yaml中的示例。 要查看API,请检查。 安装 cd Packages/Application/ git clone git@github....
提供更好的扩展性和兼容性支持。 HaloPermission解惑(Why choose "HaloPermission") 您可能对HaloPermission有诸多疑问:已经有那么多成熟的权限处理框架,为什么要用这个?这个有什么值得使用的理由?为什么这个库...
很棒的Visual Studio可扩展性 Visual Studio可扩展性资源真棒列表。 扩展名 在开发VS扩展时特别有用的VS扩展: —帮助最小化内存流量(又称GC压力)。 较小扩展名的通用礼节,较大扩展名的必要性。 指导方针和出版 ...
XAML Designer可扩展性文档和示例从Visual Studio 2019版本16.3开始,XAML设计器支持两种不同的体系结构:设计器隔离体系结构和更新的表面隔离体系结构。 详细解释了这些更改。 文件夹包含演示如何使用XAML设计器可...
Professional Visual Studio 2008 Extensibility,网上最清晰资源!
Microsoft.Windows.Design.Extensibility.dll
office open xml官方文档的第5部分,Markup Compatibility and Extensibility
ExtensibilityTools, 编写 Visual Studio 扩展的工具 面向服务的可扩展性工具 从库下载这个扩展,或者在夜间构建获取 。为 Visual Studio 扩展作者构建的扩展。有关变更和路线图,请参阅变更日志 。特性VSCT文件...
Professional VS 2008 Extensibility是讲如何扩展VS 2008的好书。
可扩展性 WixToolset.Extensibility-用于扩展WiX工具集的接口
需要写visualstudio插件的同学可以看看
MEF全称Managed Extensibility Framework(受管理扩展性框架),是微软.NET框架下为提高应用和组件复用程度而推出的。使用MEF能够使静态编译的.NET应用程序转换为动态组合,这将是创建可扩展应用、可扩展框架和应用...
Managed Extensibility Framework(MEF)是.NET平台下的一个扩展性管理框架
QTP9.5新特性 – Web插件扩展(Web Add-in Extensibility).rar
, with a focus on runtime extensibility and compile-time type safety and clarity. Table of contents Example An example of source code is shown at the bottom of this page. Installation The engine uses ...