现在的位置: 首页 > 综合 > 正文

《设计模式解析》第4章 一个标准的面向对象解决方案

2013年11月14日 ⁄ 综合 ⁄ 共 2527字 ⁄ 字号 评论关闭

4

一个标准的面向对象解决方案

概述

       本章对我们在第3章讨论的问题,“一个迫切需要灵活代码的问题”,给出一个初步的解决方案。这是一个合理的初步尝试,它能够迅速地解决问题。不过它却漏掉了一个重要的系统需求:CAD/CAM系统持续演化时所需要的灵活性。

       在本章,我基于面向对象描述了一个解决方案。它并不大,但确实能起作用。

       注意:在本章的主体部分,我将仅展示Java代码示例。对应的C++代码示例在本章的末尾。

用特殊手段来解决问题

       考虑第3章“一个迫切需要灵活代码的问题”里描述的那两个不同的CAD/CAM系统。我该怎样构建一个信息析取系统,才能使得不管使用哪一个CAD/CAM系统,对客户对象而言它看起来都是一样的呢?

       通过思考如何解决这个问题,我推断如果我能解决槽的问题,那么我也能用同样的方案来处理剪切块、洞等特性的问题。通过对槽的思考,我发现我能够轻易地特化每一种情况。也就是说,我将有一个Slot类。在面对V1系统时,我将为它生成一个派生类,在面对V2系统时,我将为它生成另一个派生类。如图4-1所示。


4-1 槽的设计

       通过对每一个特性类型进行扩展,我就完成了这个解决方案,如图4-2所示。

4-2信息析取问题的原始解决方案

       当然,图4-2展示的是相当高层的设计。每个V1xxx类将会和相应的V1库通信,而每个V2xxx类则会和V2模型中的相应对象通信。

       如果单独地来看每一个类,这个解决方案就更加容易想象了。

l           V1Slot可通过记住它所从属的模型以及被实例化时它在V1系统中的ID来实现。这样,任何时候当V1Slot的一个方法被调用以获取信息时,这个方法将不得不调用V1中的一序列子例程从而得到相关的信息。

l           V2Slot将会以一种更加简单的方式被实现,即每个V2Slot对象将会包含V2系统中的一个相应的槽对象。这样,任何时候当该对象被查询某种信息时,它将简单地将这个请求传送给OOGSlot对象并将响应回送到先前发出请求的那个客户对象。

       4-3展示了一张包含V1V2系统的更为详细的图。

4-3 初始方案

       我将为这个设计中的两个类提供代码示例。这些示例仅仅用于帮助你理解如何实现这个设计。如果你觉得你能够实现这个设计,请随意略过下面的Java代码示例(C++代码示例在本章的末尾)。

 

示例 4-1 Java代码片段:

实例化V1特性

// 实例化特性的代码片断

// 不提供错误检验——仅用作演示

 

// 每一个特性对象需要知道和它对应的模型号码以及特性ID

// 以便在收到请求时获取信息

// 注意这样的信息是如何传送进每个对象的构造函数的

 

// 打开模型

modelNum = V1OpenModel(modelName);

nElements = V1GetNumberofElements(modelNum);

Feature features[] = new Feature[MAXFEATURES];

// 为模型中的每一个特性做

for(i= 0; i < nElements; i++) {

  // 确定当前的特性并创建适当的特性对象

  switch(V1GetType(modelNum, i)) {

case SLOT:

      features[i] = new V1Slot(modelNum,

        VlGetID(modelNum, i));

      break;

    case HOLE:

      features[i] = new VlHole(modelNum,

        VlGetID(modelNum, i));

      break;

  }

}

 

示例 4-2 Java代码片断:

V1方法的实现

 

// modelNummyID是私有成员

// 它们包含对应模型和特性(在V1中的)的有关信息

class V1Slot {

  double getx () {

// V1调用适当的方法以得到所需要的信息。注意:

// 为得到信息,这个方法实际上可能调用V1中的几个方法

    return V1GetXforSlot(modelNum, myID);

  }

}

 

class VlHole {

  double getx () {

// V1调用适当的方法以得到所需要的信息。注意:

// 为得到信息,这个方法实际上可能调用V1中的几个方法

return V1GetXforHole(modelNum, myID);

}

}

 

示例 4-3 Java代码片段:

初始化V2特性

// 实例化特性的代码片断

// 不提供错误检验——仅用作演示

 

// 每一个特性对象需要知道它在V2中对应的特性

// 以便在收到请求时获取信息

// 注意这样的信息是如何传送进每个对象的构造函数的

 

// 打开模型

myModel = V2OpenModel(modelName);

nElements = myModel.getNumElements();

Feature features[] = new Feature[MAXFEATURES];

(待续)

示例 4-3 Java代码片段:[1]

初始化V2特性(继续)

OOGFeature *oogF;

// 为模型中的每一个特性做

for (i= 0; i < nElements; i++) {

  // 确定当前的特性并创建适当的特性对象

  oogF = myModel->getElement(i);

  switch(oogF->myType()){

    case SLOT:

      features[i] = new V2Slot(oogF);

      break;

    case HOLE:

      features[i] = new V2Hole(oogF);

      break;

  }

}

示例4-4 Java代码片段:

V2方法的实现

// oogFV2中对应的特性对象

class V2Slot {

  double getX (} {

    // 调用oogF的适当方法以得到所需的信息。

    return oogF->getX();

  }

}

class V2Hole {

  double getX () {

  // 调用oogF的适当方法以得到所需的信息。

  return oogF->getX();

抱歉!评论已关闭.