• 网络学院
  • IT资讯
  • 操作系统
  • 网络技术
  • 软件应用
  • 办公软件
  • 编程技术
  • 网站架设
  • 数据库类
  • 平面设计
  • 多媒体类
  • 游戏资讯
  • 教学论文
  • 认证考试
封装的变化之排序算法中的封装
  站点:
  • 首 页
  • 最新软件
  • 文章教程
  • 国内软件
  • 国外软件
  • 绿色软件
  • 源码下载
  • 字体下载
封装的变化之排序算法中的封装
软件发布 封装的变化之排序算法中的封装
网络软件 系统工具 应用软件 联络聊天 图形图像 多媒体类 行业软件 游戏娱乐 编程开发 安全相关 教育教学 数码软件 绿软下载
热门软件: QQ 瑞星 pplive e话通 木马克星 千千静听 office2000 五笔字根 Photoshop 视频分割
返回文章教程首页 >> 文章首页 >> 认证考试 >> 系统工程师 >> 封装的变化之排序算法中的封装

封装的变化之排序算法中的封装

添加时间: 2007-4-9 3:06:38  作者: 系统工程师认证参考  阅读次数:20   来源: http://www.d9soft.com

       

  设想这样一个需求,我们需要为自己的框架提供一个负责排序的组件。目前需要实现的是冒泡排序算法和快速排序算法,根据“面向接口编程”的 思想 ,我们可以为这些排序算法提供一个统一的接口isort,在这个接口中有一个方法sort(),它能接受一个object数组参数。对数组进行排序后,返回该数组。接口的定义如下:

  public interface isort
{
 void sort(ref object[] besorted);
}

  其类图如下:

 

  然而一般对于排序而言,排列是有顺序之分的,例如升序,或者降序,返回的结果也不相同。最简单的方法我们可以利用if语句来实现这一目的,例如在quicksort类中:

  public class quicksort:isort
{
 private string m_sorttype;
 public quicksort(string sorttype)
 {
  m_sorttype = sorttype;
 }
 public void sort(ref object[] besorted)
 {
  if (m_sorttype.toupper().trim() == “ascending”)
  {
   //执行升序的快速排序;
  }
  else
  {
   //执行降序的快速排序;
  }
 }
}

  当然,我们也可以将string类型的sorttype定义为枚举类型,减少出现错误的可能性。然而仔细阅读代码,我们可以发现这样的代码是非常僵化的,一旦需要扩展,如果要求我们增加新的排序顺序,例如字典顺序,那么我们面临的工作会非常繁重。也就是说,变化产生了。通过分析,我们发现所谓排序的顺序,恰恰是排序算法中最关键的一环,它决定了谁排列在前,谁排列在后。然而它并不属于排序算法,而是一种比较的策略,后者说是比较的行为。

  如果仔细分析实现isort接口的类,例如quicksort类,它在实现排序算法的时候,需要对两个对象作比较。按照重构的做法,实质上我们可以在sort方法中抽取出一个私有方法compare(),通过返回的布尔值,决定哪个对象在前,哪个对象在后。显然,可能发生变化的是这个比较行为,利用“封装抽象”的 原理 ,就应该为该行为建立一个专有的接口icompare,然而分别定义实现升序、降序或者字典排序的类对象。

  我们在每一个实现了isort接口的类构造函数中,引入icompare接口对象,从而建立起排序算法与比较算法的弱耦合关系(因为这个关系与抽象的icompare接口相关),例如quicksort类:

  public class quicksort:isort
{
 private icompare m_compare;
 public quicksort(icompare compare)
 {
  m_compare= compare;
 }
 public void sort(ref object[] besorted)
 {
  //实现略
  for (int i = 0; i < besorted.length - 1; i++)
  {
   if (m_compare.compare(besorted[i],besorted[i+1))
   {
    //略;
   }
  }
  //实现略

  通过对比较策略的封装,以应对它的变化,显然是stategy模式的设计。事实上,这里的排序算法也可能是变化的,例如实现二叉树排序。由于我们已经引入了“面向接口编程”的 思想 ,我们完全可以轻易的添加一个新的类binarytreesort,来实现isort接口。对于调用方而言,isort接口的实现,同样是一个strategy模式。此时的类结构,完全是一个对扩展开发的状态,它完全能够适应类库调用者新需求的变化。

  再以petshop为例,在这个项目中涉及到订单的 管理 ,例如插入订单。考虑到访问量的关系,petshop为订单管理提供了同步和异步的方式。显然,在实际应用中只能使用这两种方式的其中一种,并由具体的应用环境所决定。那么为了应对这样一种可能会很频繁的变化,我们仍然需要利用“封装变化”的 原理 ,建立抽象级别的对象,也就是iorderstrategy接口:

  public interface iorderstrategy
{
 void insert(petshop.model.orderinfo order);
}

  然后定义两个类ordersynchronous和orderasynchronous。类结构如下:

  在petshop中,由于用户随时都可能会改变插入订单的策略,因此对于业务层的订单领域对象而言,不能与具体的订单策略对象产生耦合关系。也就是说,在领域对象order类中,不能new一个具体的订单策略对象,如下面的代码:

  在martin fowler的文章《ioc容器和dependency injection模式》中,提出了解决这类问题的办法,他称之为依赖注入。不过由于petshop并没有使用诸如sping.net等ioc容器,因此解决依赖问题,通常是利用配置文件结合反射来完成的。在领域对象order类中,是这样实现的:

  public class order
{
 private static readonly iorderstategy orderinsertstrategy = loadinsertstrategy();
 private static iorderstrategy loadinsertstrategy()
 {
  // look up which strategy to use from config file
  string path = configurationmanager.appsettings["orderstrategyassembly"];
  string classname = configurationmanager.appsettings["orderstrategyclass"];

  // load the appropriate assembly and class
  return (iorderstrategy)assembly.load(path).createinstance(classname);
 }
}

  在配置文件web.config中,配置如下的section:

  <add key="orderstrategyassembly" value="petshop.bll"/>
<add key="orderstrategyclass" value="petshop.bll.ordersynchronous"/>

  这其实是一种折中的service locator模式。将定位并创建依赖对象的逻辑直接放到对象中,在petshop的例子中,不失为一种好方法。毕竟在这个例子中,需要依赖注入的对象并不太多。但我们也可以认为是一种无奈的妥协的办法,一旦这种依赖注入的逻辑增多,为给程序者带来一定的麻烦,这时就需要一个专门的轻量级ioc容器了。

  写到这里,似乎已经脱离了“封装变化”的主题。但事实上我们需要明白,利用抽象的方式封装变化,固然是应对需求变化的王道,但它也仅仅能解除调用者与被调用者相对的耦合关系,只要还涉及到具体对象的创建,即使引入了工厂模式,但具体的工厂对象的创建仍然是必不可少的。那么,对于这样一些业已被封装变化的对象,我们还应该充分利用“依赖注入”的方式来彻底解除两者之间的耦合。

 

 

上下文章:

 

上一篇文章: 浅谈PHP开发团队的管理之道 下一篇文章: 如何做好网站开发项目需求分析

相关文章:

  • Oracle10gRelease2新功能之变化通知
  • Oracle9i到10g,空闲等待事件的变化
  • 使用排序哈希簇来加提高询速度
  • Oracle9i到10g,空闲等待事件的变化
  • 使用排序哈希簇来加提高询速度

相关软件:

  • 万能驱动包(封装专用) V7.10 简体中文版
  • DES加密算法及有关说明(HTM)

 

快速导航

  • 网络学院
  • 精品汇聚
  • 字体下载
  • 教程下载
  • ASP源码
  • PHP源码
  • Net源码
  • JSP 源码

认证考试分类导航

  • 微软认证
  • 计算机等级考试
  • 软件水平考试
  • 思科认证
  • Oracle认证
  • Linux认证
  • JAVA认证
  • 网络工程师
  • 系统工程师
  • 程序员

本类经典文章推荐

  • SQLServer的安全检查
  • 系统设计师资格与水平考纲 (原高级...
  • 系统分析员备考之ISO9000系列基础...
  • 开发数据库的WEB查询
  • 在builder中向Excel传递数据
  • 用Powerbuilder开发WEB数据库
  • PowerBuilder制作IE风格的图标按钮
  • PowerBuilder编程技巧四则
  • 小议数据库主键选取策略
  • 跨数据库文献检索统一平台的实现

系统工程师阅读排行

  • 数据库原理各章节简答题总结
  • 利用C++Builder6.0开发简单的车辆...
  • 跨数据库文献检索统一平台的实现
  • 用Powerbuilder开发WEB数据库
  • 系统设计师资格与水平考纲 (原高级...
  • 项目进度的黑洞——已完成90%
  • 系统分析员备考之ISO9000系列基础...
  • 小议数据库主键选取策略
  • 数据库系统工程师全真预测试卷(一...
  • 2005年上半年数据库系统工程师上午...

认证考试阅读总排行

  • 全国计算机等级考试一级模拟试题01
  • 全国计算机等级考试一级模拟试题10
  • 全国计算机等级考试一级模拟试题08
  • MCSD简介
  • 全国计算机等级考试一级考试最新模...
  • 全国计算机等级考试一级模拟试题07
  • 全国计算机等级考试一级模拟试题02
  • 全国计算机等级考试一级模拟试题06
  • 全国计算机等级考试一级模拟试题03
  • 一级(WINDOWS)试题解析-Word篇

广告位置

字母检索 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 回到顶部

关于我们 | 版权声明 | 免责条款 | 广告联系 | 软件发布 | 下载帮助 | 下载排行 | 网站地图 | 特别鸣谢 | 友情连接

copyright; 2005-2008 D9soft.com 第九软件网 版权所有