设计是一种思想,而软件设计模式是人们在长期的软件开发经验中提取出来
的通用方法并被实践证明是确切可行的,把模式应用到设计之中,会让我们的软
件更加强健,让我们的开发更加高效。
现在我们可以开始来探讨业务逻辑层的设计方法。在本文中说的是利用接口
来封装账户管理实现的变化。
在设计中,我们常常会遇到同一功能被要求用不同方法进行实现的问
题。比如说在一个软件的业务逻辑层设计中,用户的用户管理(注册、登录、注
销、修改)模块部分首先实现的是本地账户的登录功能,账户用一个本地文件进
行存储操作。但客户这时却说将来他们希望该软件能够实行远程登录,用一个服
务器来存储用户资料。这意味着要改变已经编写好的代码来满足客户的要求,考
虑到用户管理是一个常用的操作,且它实现的业务逻辑是通用的,界面也是相同
的。我们可以把它做成一个接口,那么以后需要编写用户管理时直接使用这个接口便可。一个软件设计思想是,把变化的部分封装起来,即提取它们的共同功能
用接口或抽象类封装起来,之所以说变化是因为这些共同功能有不同的实现。
根据这种思想,我们可以设计一个接口类UserOperate,再用两个类分别实
现这个接口,其中本地用户管理类为LocalUserOP,而远程用户管理类为
NetUserOp。实现的类图如下:
在接口中定义的函数提供了注册、登录、注销、修改和检查登录等统一接
口。而实现的两个子类可以对这些功能有不同的实现方法。比如register函数的
注册功能,本地账户LocalUseOP类在register中调用数据访问层的函数
appendToUserFile(user) 把该账户写进本地文件中。而NetUserOP则可能调用
函数 sendRegisterCommand(user) 将账户传给远程服务器请求注册。尽管它
们的实现有天和地一般的差别,但是因为接口的封装,在整个系统中会带来极大
的便利。比如说要实现网络功能,只需要写上
UserOperate userOp = new NetUserOP( serverIp,serverPort);
在表示层中用户需要注册新账号时,只需要简单调用userOp.register(user)即
可。如果用户又希望转变为本地用户管理,仅需new那段代码改为
UserOperate userOp = new LocalUserOP( fileName);
即可,其它地方的代码完全不需要更改!
由上面我们也可以看到一个流程,即表示层调用业务逻辑层,业务逻辑层调
用数据访问层处理逻辑并返回数据给表示层。在这设计之中我们使用了接口来封
装,使得表示层可以很容易的使用业务逻辑层的功能,也减弱了层与层之间的耦
合度。
有点累了,改天再更新另外一个很实用的观察者模式。