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. 洛谷1034 NOIP2002 矩形覆盖

    问题描述 在平面上有 n 个点(n <= 50),每个点用一对整数坐标表示.例如:当 n=4 时,4个点的坐标分另为:p1(1,1),p2(2,2),p3(3,6),P4(0,7). 这些点可以 ...

  2. 今日SGU 5.30

    SGU 190 题意:给你个n*n的矩形,然后上面有几个点不能放东西,然后问你能不能用1*2的矩形,把能放 东西的地方放满 收获:一开始想的是,dfs,然后感觉这样的话,代码很长,而且很容易超时, 看 ...

  3. Oracle基础入门(三)

    一:PLsql一些基本操作 调节plsql的字体大小 二:创建表,如果学过sql server的数据库就会发现其实Oracle跟的一些新建表和新增修改其实是差不多的 新建表 Create table ...

  4. 洛谷 P1898 缘分计算

    P1898 缘分计算 题目描述 缘分是一个外国人难以理解的中文名词.大致说来,缘分是一种冥冥中将两人(通常是情人)结合的力量.仅管这是种迷信,很多人——特别是女生——喜欢去计算它. 不幸的是,644 ...

  5. git commit template

    https://www.zhihu.com/question/27462267/answer/204658544 https://gist.github.com/adeekshith/cd4c95a0 ...

  6. sklearn preprocessing 数据预处理(OneHotEncoder)

    1. one hot encoder sklearn.preprocessing.OneHotEncoder one hot encoder 不仅对 label 可以进行编码,还可对 categori ...

  7. Codeforces 344A Magnets

    Description Mad scientist Mike entertains himself by arranging rows of dominoes. He doesn't need dom ...

  8. 随机模拟的基本思想和常用采样方法(sampling)

    转自:http://blog.csdn.net/xianlingmao/article/details/7768833 引入 我们会遇到很多问题无法用分析的方法来求得精确解,例如由于式子特别,真的解不 ...

  9. javaScript for in循环遍历对象

    for循环常被我们用来遍历数组,而如何遍历对象呢? 这时就需要用到for in循环了 写一个遍历对象名简写如下: for(var xxx in ooo){console.log(xxx)} 其中xxx ...

  10. Swift学习笔记(8)--函数

    1.定义及调用 func sayHelloAgain(personName: String) -> String { return "Hello again, " + per ...