编程基本功(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. 长处:改动行为easy,由于这里往往代表了数据,即便多处引用也不会影响到。缺点:改动数据结构困难,多处引用的话会影响到非常多地方。
对象
对象往往和接口关系紧密,上例相应的接口演示样例:
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. 长处:由于数据结构封装了,因此改动数据结构easy。接口是一张对象能力(行为)清单。改动成本较大(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,除非确保定义的非常全面,否则一旦改动将会影响全局,而增添一个异常类比較easy
2. easy出现反复定义
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。