`
mybwu_com
  • 浏览: 179757 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

编程基本功(4)

 
阅读更多

编程基本功 (4)

数据结构与对象

数据结构

在OO世界里,数据结构往往意味着没有任何能力的纯实体,这种情况是很少见的(因为意味着纯粹数据结构的集成)。

例子:

public struct Point {
public double X {get; set;}
public double Y {get; set;}
private double x;
private double y;
}


1. 我们可以用它来存一个点,这个点可以是任何形状的一部分

2. 它不具备任何能力,仅仅是对数据的集成而已

3. 优点:修改行为容易,因为这里往往代表了数据,即便多处引用也不会影响到;缺点:修改数据结构困难,多处引用的话会影响到很多地方。

对象

对象往往和接口关系紧密,上例对应的接口示例:

public interface Point {
double getX();
double getY();
void setCartesian(double x, double y);
double getR();
double getTheta();
void setPolar(double r, double theta);
}


1. 数据被封装了

2. 暴露了一些对象的能力可以使用,但基于封装

3. 优点:由于数据结构封装了,因此修改数据结构容易;接口是一张对象能力(行为)清单,修改成本较大(open-close 原则,通常只增加接口)。

结论:

过程式设计使得修改function时无需修改数据结构(纯实体类);OO设计可以通过增加类的方式来扩展功能而无需修改已有的function。

过程式设计修改数据结构很困难,因为所有引用到的地方都要改;OO设计需改接口很麻烦因为所有相关类都要改(因此较早考虑轻量接口,开发过程只增加接口)。

避免冗长的调用

看下面这行代码:

string outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();


显然如果重构一下:

string outputDir = GetAbsolutePath();
 
private string GetAbsolutePath(){
return ctxt.getOptions().getScratchDir().getAbsolutePath();
}


代码的意图清晰很多,调用者也方便很多。

使用抛出Exception而不是Return ErrorCode

1.ErrorCode是一个全局的level,除非确保定义的非常全面,否则一旦修改将会影响全局,而增添一个异常类比较容易

2. 容易出现重复定义

3. 异常可以使用wrapper来接触错误处理和business之间的耦合,可是使用errorcode无法解耦。

Wrapper Exception

看这段code:

try {
port.open();
} catch(DeviceResponseException e) {
reportPortError(e);
logger.log("Deviceresponse exception", e);
} catch(ATM1212UnlockedException e) {
reportPortError(e);
logger.log("Unlockexception", e);
} catch (GMXErrore) {
reportPortError(e);
logger.log("Deviceresponse exception");
}


如果多处需要调用port.open函数,那么到处都是这种catch chain。解决办法是对port进行wrap,把catch chain wrap起来:

public class LocalPort {
private ACMEPort innerPort;
public LocalPort(int portNumber) {
innerPort =new ACMEPort(portNumber);
}
 
public void open() {
try {
innerPort.open();
} catch(DeviceResponseException e) {
throw new PortDeviceFailure(e);
} catch(ATM1212UnlockedException e) {
throw new PortDeviceFailure(e);
} catch(GMXError e) {
109 Definethe Normal Flow
throw new PortDeviceFailure(e);
}
}
…
}


这样就使得调用的代码意图清晰很多:

try {
port.open();
} catch(PortDeviceFailure e) {
reportError(e);
logger.log(e.getMessage(),e);
}


Wrapper其实就是Adapter模式的应用之一,除了异常,还可以对第三方library以及其他API的调用进行wrap。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics