`

可扩展性(Extensibility)——构建灵活系统的思考

阅读更多

参考资料:

《设计模式——可复用面向对象软件的基础》

《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)要想获得可扩展性,你需要看得远一点,对上下文做充分的了解。

 

      人无远虑,必有近忧。

 

      系统也一样。

 

 

 

6
0
分享到:
评论

相关推荐

    QTP9.5新特性 – Web插件扩展(Web Add-in Extensibility).rar

    在QTP 9.5版本中,引入了一个重要的新特性——Web插件扩展(Web Add-in Extensibility),这个特性极大地增强了QTP对Web应用测试的支持和定制能力。本文将详细介绍这一特性,并探讨其在实际测试工作中的应用。 **一...

    ASP.NET源码——[其他类别]Microsoft .NET Framework 4.0 Beta 1 (x86).zip

    9. **扩展性和可维护性**:.NET Framework 4.0提供了更好的扩展性,例如,通过MEF(Managed Extensibility Framework)来支持插件架构,增强了应用程序的灵活性和可维护性。 压缩包中的"dotNetFx40_Full_x86.exe"是...

    企业级应用软件架构开发过程与实践1

    **移植适应性Portability与可扩展性Extensibility要求** 移植适应性强调软件能够在不同硬件平台或操作系统上运行的能力,而可扩展性则关注软件能否轻松添加新功能或模块。 **软件开发阶段内部质量要求** 在软件...

    面向对象与对象模型面向对象与对象模型

    6. 可扩展性原则(Extensibility):允许在不修改现有代码的情况下添加新功能。 7. 抽象(Abstraction):关注对象的主要特征,忽略不必要的细节。 实现这些原则的方法包括: 1. 分解与封装:将复杂问题分解为独立...

    System.ComponentModel.Composition.Initialization.dll

    通过这个库,开发者可以定义自己的组件,并在运行时由MEF自动发现和管理这些组件,极大地提高了代码的可维护性和可扩展性。 在Silverlight Toolkit中,System.ComponentModel.Composition.Initialization.dll的作用...

    RFID EPC概述

    - **可扩展性(Extensibility)**:随着需求的变化,编码体系能够灵活调整。 - **媒介(Media)**:支持多种数据载体。 - **数据传输机制(Data Transmission Mechanisms)**:定义了编码数据的传输方式。 - **保密性与...

    brownant_code.zip

    7. **可扩展性与模块化(Extensibility and Modularity)**: 优秀的框架应具备良好的可扩展性和模块化设计,使得用户可以方便地添加新的解析规则,或者对接自定义的存储和处理模块。 综上所述,"Brownant_code....

    25个优秀的_ASP.NET_MVC教程及文章

    - **可扩展性机制**:解释 ASP.NET MVC 设计的核心理念之一——可扩展性。 - **自定义组件**:介绍如何创建自定义组件和服务来替换默认组件,满足特定需求。 - **扩展点概述**:逐一列举并解释 ASP.NET MVC 中的关键...

    PyPI 官网下载 | databand-0.49.0.tar.gz

    5. **可扩展性(Extensibility)**:databand支持与各种数据处理框架(如Spark、Pandas、Dask等)集成,可以轻松地添加自定义操作,扩展其功能。 6. **异常检测与恢复(Error Detection and Recovery)**:databand...

    Visual Studio 2013 SDK 官方安装版

    7. **Mef(Managed Extensibility Framework)**:这是一个用于构建可扩展应用程序的.NET框架,Visual Studio 2013 SDK利用Mef实现插件的加载和管理,使得扩展的开发更加灵活和模块化。 8. **文档和示例**:Visual ...

    JAVA后端高级工程师面试题

    2. 服务端:采用面向接口编程,减少耦合,使用MEF(Managed Extensibility Framework)实现依赖注入,增强可扩展性。AOP(面向切面编程)如Postsharp处理异常、权限验证和日志记录,提高代码复用性。 3. 技术栈:BS...

    Visual Studio扩展性(第2天):通过持续集成在登台服务器和GIT上部署Visual Studio Extension

    在本篇关于“Visual Studio扩展性(第2天)”的文章中,我们将深入探讨如何利用Git版本控制系统和持续集成服务,如AppVeyor,来实现Visual Studio Extension(VSIX)的自动化部署流程。这对于软件开发团队来说尤其...

    Laravel开发-eav

    在IT行业中,Laravel是一个非常流行的开源PHP框架,它被广泛用于构建优雅、高效和可扩展的Web应用程序。"Laravel开发-eav"这个主题聚焦于Laravel框架中的一种特定数据模型设计模式——实体属性值(Entity-Attribute-...

    23个.NET开源项目

    - **Managed Extensibility Framework (MEF)**:这是一种动态可扩展的框架,允许应用程序在运行时动态加载和扩展功能,极大地提升了软件的灵活性和可维护性。 #### Web应用框架与架构 - **s#arp architecture for ...

    liquid:Clojure文本编辑器,用于编辑Clojure代码和降价。 完全由Clomacre撰写,灵感来自Emacs和Vim

    liquid编辑器正是为了满足Clojure开发者的需求而诞生,它提供了丰富的功能和高度的可扩展性。 首先,liquid编辑器的核心特性是对Clojure代码的完美支持。它具备智能感知、自动完成、语法高亮等特性,使编写Clojure...

    精通IIS7电子书2008版

    ##### 第12章:核心服务器扩展性(Chapter 12: Core Server Extensibility) IIS 7.0的核心服务器具有良好的扩展性,可以通过编写自定义模块来实现特定的功能需求。本章详细介绍了如何开发自定义模块,包括模块注册...

    Professional C# 2012 and .NET 4.5.pdf

    MEF(Managed Extensibility Framework)是一种插件框架,用于创建可扩展的应用程序。 ### Windows Runtime(第31章) 介绍了Windows Runtime(WinRT)平台,这是Windows 8和后续版本操作系统的核心API。 ### 数据...

    simter-sso-core:SSO 核心

    7. **扩展性和定制化(Extensibility and Customization)**:作为核心组件,Simter SSO Core应该支持与其他系统集成,如LDAP、AD等目录服务,以及提供API和事件驱动的扩展点,以便根据企业需求进行定制。...

    环视.NET Framework ppt

    通过MEF,.NET应用程序可以从静态编译转变为动态组合,从而更好地遵循开闭原则——即软件实体应当对扩展开放,对修改关闭。 ##### 3.4 Entity Framework 4 - **Model-First**:这是一种新的开发模式,允许开发者...

Global site tag (gtag.js) - Google Analytics