Preface:

合理的软件架构设计其好处是不言而喻的,系统具有清晰的软件结构,良好的可扩展性,类的职能单一明确,系统的复杂度底。此前的一个实际项目中总结了些关于OO设计的实际应用,主要是围绕‘高内聚及松耦合’,‘开闭原则’的一些应用。

Problem: 

目前有一个实际应用放在我们面前,为一个银行现有BI系统开发WebService对外数据接口应用,数据交换方式以预定请求及响应报文来完成,要求可以数据接口系统跨平台使用。即远程客户端发来一种XML数据请求报文,系统按类型执行查询,然后返回XML数据响应报文。

问题也浮出水面,通常此类系统中我们可以想像到,其中一定会有一系列的if else来判断是何种请求报文,然后再执行对应的动作,但我们如果我们这样设计,系统就违反了开放-封闭原则 (OCP,Open-Close Principle),日后的扩展一定需要修改原有代码,而我们期望的是日后添加一种新报文后,只在系统中扩展新的请求、查询及响应对象来实现新需求。

带着问题思考解决办法...

补充:敏捷设计扩展知识手册

拙劣设计的症状:

1.僵化性(Rigidity):设计难以改变。很难对系统进行改动,因为每个改动都会迫使许多对系统其他部分的其他改动。

2.脆弱性(Fragility):设计易于遭到破坏。对系统的改动会导致系统中和改动的地方在概念上无关的许多地方发现问题。3.牢固性 (Immobility):设计难以重用。很难解开系统的纠结,使之成为一些可在其他系统中重用的组件。

4.粘滞性(Viscosity):难以做正确的事情。做正确的事情比做错误的事情要困难。

5.不必要的复杂性(Needless Complexity):过分设计。设计中包含有不具有任何直接好处的基础结构。

6.不必要的重复性(Needlsee Repetition):滥用复制/粘贴。设计中包含有重复的结构,而该重复的对象本可以使用单一的抽象进行统一。

7.晦涩性(Opacity):很难阅读、理解。没有很好的表现出意图。

面向对象的设计原则:

1.单一职责原则 (SRP,Single Resposibility Principle)

2.开放-封闭原则 (OCP,Open-Close Principle)

3.Liskov替换原则 (LSP,Liskov Principle)

4.依赖倒置原则 (DIP,Dependicy Independent Priciple)

5.接口隔离原则 (ISP,Interface Seperation Principle)

Solution:

我们初步的想法是,系统接受到一种XML请求后将其转换成请求对象,类似多态的方法,根据不同的请求对象由查询工厂来创建返回不同的查询处理类,再由查询处理类返回填充好的数据响应对象,最后转换成XML响应报文。由此思路,我们完成了UML类图设计,如下:

首先是RemoteQueryService 接口,系统对外的WS服务由此接口完成。

  1. /**
  2. * 类说明: WS远程服务接口<br>
  3. * 创建时间: 2009-11-6 上午10:07:55<br>
  4. *
  5. * @author Seraph<br>
  6. * @email seraph115@gmail.com<br>
  7. *
  8. */
  9. public interface RemoteQueryService {
  10. /**
  11. * 功能说明: <br>
  12. * 创建者: Seraph<br>
  13. * 创建时间: 2009-11-6 上午10:08:09<br>
  14. *
  15. * @param request
  16. * @return
  17. */
  18. @Profiled(tag = "RemoteQueryService")
  19. public String doQuery(String request);
  20. }

RemoteQueryServiceImpl 类是此接口的实现,接口方法为接受一种XML请求报文然后返回响应报文。

RegisterContainer 类,在系统初始化时完成不同请求所对应的查询处理类的注册。

QueryFactory 类,根据不同的请求对象返回不同的查询处理类。

ParserRobot 类,负责将XML请求转换为Java请求对象,将Java响应对象转换为XML报文。

QueryProvider 抽象类,是不同种查询处理类的父类。

Request 类,是请求对象的父类。

Response 类,是响应对象的父类。

其中QueryProvider 类,doQuery抽象方法由继承后的子类实现,用来实现不同种报文的查询处理方法,代码为:

  1. /**
  2. * 类说明: <br>
  3. * 创建时间: 2009-11-6 上午10:21:30<br>
  4. *
  5. * @author Seraph<br>
  6. * @email seraph115@gmail.com<br>
  7. *
  8. */
  9. @Service
  10. public abstract class QueryProvider {
  11. private QueryDaoSupport queryDaoSupport;
  12. private SqlProvider sqlProvider;
  13. public abstract Response doQuery(Request request) throws BrwsException;
  14. public QueryDaoSupport getQueryDaoSupport() {
  15. return queryDaoSupport;
  16. }
  17. public void setQueryDaoSupport(QueryDaoSupport queryDaoSupport) {
  18. this.queryDaoSupport = queryDaoSupport;
  19. }
  20. public SqlProvider getSqlProvider() {
  21. return sqlProvider;
  22. }
  23. public void setSqlProvider(SqlProvider sqlProvider) {
  24. this.sqlProvider = sqlProvider;
  25. }
  26. }

由UML图中,我们可以看到Request , QueryProvider , Response有许多对应的子类,而每个子类都是一种报文类型,也就是系统所能提供的查询服务。所以目前的架构设计下,日后添加一种新报文将很容易,只需要实现一组 Request, QueryProvide及Response就可以完成新报文的实现,从而达到了松耦合、可扩展的设计。

Webservice银行报文接口设计的更多相关文章

  1. 优秀的API接口设计原则及方法(转)

    一旦API发生变化,就可能对相关的调用者带来巨大的代价,用户需要排查所有调用的代码,需要调整所有与之相关的部分,这些工作对他们来说都是额外的.如果辛辛苦苦完成这些以后,还发现了相关的bug,那对用户的 ...

  2. 基于PCIe的高速接口设计

    基于PCIe的高速接口设计 由 judyzhong 于 星期四, 03/03/2016 - 13:49 发表 作者:李晓宁,姚远程,秦明伟 2016年微型机与应用第1期 摘要:PCIe总线是第三代I/ ...

  3. C#winForm调用WebService的远程接口

    Web Service 的创建简单编码.发布和部署 上一篇详细概述了WebService的创建,编码,发布和部署,那么作为客户端的程序如何访问远程端的WebService 接下来看一下具体步骤:   ...

  4. 数据仓储之DLL层接口设计

    一.接口设计 1.1. IBaseRepository.cs public interface IBaseRepository<T> { T Add(T entity); bool Upd ...

  5. RESTful接口设计原则/最佳实践(学习笔记)

    RESTful接口设计原则/最佳实践(学习笔记) 原文地址:http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api 1 ...

  6. Web API接口设计经验总结

    在Web API接口的开发过程中,我们可能会碰到各种各样的问题,我在前面两篇随笔<Web API应用架构在Winform混合框架中的应用(1)>.<Web API应用架构在Winfo ...

  7. Verilog学习笔记简单功能实现(七)...............接口设计(并行输入串行输出)

    利用状态机实现比较复杂的接口设计: 这是一个将并行数据转换为串行输出的变换器,利用双向总线输出.这是由EEPROM读写器的缩减得到的,首先对I2C总线特征介绍: I2C总线(inter integra ...

  8. atitit.基于http json api 接口设计 最佳实践 总结o7

    atitit.基于http  json  api 接口设计 最佳实践 总结o7 1. 需求:::服务器and android 端接口通讯 2 2. 接口开发的要点 2 2.1. 普通参数 meth,p ...

  9. App接口设计

    关于APP接口设计 http://blog.csdn.net/gebitan505/article/details/37924711/

随机推荐

  1. bzoj1230 开关灯 线段树

    好久没写线段树了..被一道线段树裸题卡了一个上午 对区间进行异或,查询的时候直接用区间长度减去原有是数量就是改变完的数量 #include<bits/stdc++.h> using nam ...

  2. 二叉查找树BST 模板

    二叉查找树BST 就是二叉搜索树 二叉排序树. 就是满足 左儿子<父节点<右儿子 的一颗树,插入和查询复杂度最好情况都是logN的,写起来很简单.   根据BST的性质可以很好的解决这些东 ...

  3. hdu 5412 CRB and Queries(整体二分)

    题意 动态区间第k大 (n<=100000,m<=100000) 题解 整体二分的应用. 与静态相比差别不是很大.(和CDQ还有点像)所以直接上代码. #include<iostre ...

  4. [Recompose] Compose Streams of React Props with Recompose’s compose and RxJS

    Functions created with mapPropsStream canned be composed together to build up powerful streams. Brin ...

  5. POJ 1088: 滑雪(经典 DP+记忆化搜索)

    滑雪 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 74996   Accepted: 27818 Description ...

  6. 理解ThreadLocal类

    1 ThreadLocal是什么 早在JDK 1.2的版本号中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路. 使用这个工具类能够 ...

  7. 同学们,OpenCV出3.0了,速去围观!

    OpenCV3.0 OpenCV > NEWS > OpenCV 3.0 2015-06-04 With a great pleasure and great relief OpenCV ...

  8. 用户向导左右滑动页面实现之ImageSwitcher

    当第一次打开一个app时,通常有一个使用向导介绍本APK的基本功能和用法,这个向导是很重要的,方便用户能高速知道和适应该app如何用. 实现此使用向导有非常多种方法,比方用ImageSwitcher, ...

  9. 利用netstat和tasklist查看PC的端口占用情况 及80端口被占用

    经常,我们在启动应用的时候发现系统需要的端口被别的程序占用,如何知道谁占有了我们需要的端口? 1.Windows平台在windows命令行窗口下执行: E:\oracle\ora92\bin>n ...

  10. noip 2018 day1 T1 铺设道路 贪心

    Code: #include<cstdio> using namespace std; int main() { int last=0,ans=0; int n;scanf("% ...