概述
此文章其实主要就是概括一下,在开发一个功能/需求的时候,我们如何通过面向对象去进行需求的分析设计和开发,以达到提升开发效率,提高系统的可维护性。
首先我先将步骤要点概括一下,然后再根据最近实现的需求作为案例讲解一下。
在接到新的需求然后进行开发的话,主要是基于以下三个步骤
1、面向对象分析
2、面向对象设计
3、面向对象变成
面向对象分析(OOA)
其实一句简单的话概括就是 :沟通、分析需求、自身给出假设、梳理功能点,粗略的概括的话就是:需求分析,就是面向对象的分析了。
但是在理清需求的途中,是不可能一次性就将需求要做的功能点,以及实现的大概流程一下就梳理出来的。而是一个不断迭代的过程。我个人将需求分析总结为以下几点:
1、battle需求,最好是从客户以及业务场景上去想,至于能否实现,我现在是觉得所有需求都是能实现的(只是实现的代价,以及自己会不会而已哈哈)
2、理清需求,分点罗列需求需要实现的功能
3、根据罗列的功能,直接分点提出功能实现的技术方案(简单概括即可)
4、根据粗略提出的需求方案提出疑问,哪里漏了、有没有安全问题、以后会不会扩展、该如何扩展、是否可落地
5、根据提出的问题进行技术方案的修正
6、 while(4、5) {if (noProblem) return};
根据上边的几个步骤,我们已经有个初步的方案了。然后就开始进入到我们的第二步,面向对象设计
面向对象设计(OOD)
在经过面向对象分析的之后,我们已经对需求有一个整体的了解,并且已经知道实现新需求的功能有个整体的技术方案/想法,此时我们就可以通过面向对象设计,根据分析出来的技术方案,将其转化为面向对象的各种类。
至于面向对象设计的步骤的话,最近看了 设计模式之美,我就直接写上文中所教的步骤吧
1、划分职责进而识别出有哪些类;
2、定义类及属性和方法;
3、定义类与类间的交互关系;
4、将类封装起来并提供执行入口
至于这几个步骤怎么用,可以先记者,后续说案例的时候会有讲。
然后在讲过面向对象设计之后,我们已经将类,属性,方法和交互关系定义好了。此时就到最后一步,面向对象编程即可
面向对象编程(OOP)
此时就根据面向对象设计中定义好的类,进行代码的填写即可。至于类的定义只是比较大概的,到了代码编写的时候,可能有些复杂的功能就需要用到一些设计原则和设计模式,就不在这里细讲了,推荐个网站去学习下:常用设计模式有哪些?
案例
分析
需求:存在netty客户端和 netty服务端,你需要写netty客户端程序,主要做的功能就是,根据服务端传递过来的操作和对象信息,然后修改当前客户端存在的日志服务器的配置文件进行修改。
如果直接接到此需求的时候,其实很多信息都不怎么清晰,比如服务端传过来的信息是怎样的,比如服务器的配置文件是怎样的。。等等,这些都是需要我们的第一步沟通需求。沟通完需求之后,
我们要做的是逐句阅读上面的需求描述,拆解成小的功能点,一条一条罗列下来。注意,拆解出来的每个功能点要尽可能的小。每个功能点只负责做一件很小的事情。下面是我逐句拆解上述需求描述之后,得到的功能点列表
功能点
1、写一个netty客户端连接已有的netty服务端
2、接收服务端传过来的信息 (信息内容存在为 -> operate:增/删/改, logObject:需要操作的日志对象内容)
3、根据接收的信息,对 配置文件内容进行修改
初步方案
第一版:
1、使用netty连接服务端
2、解析接收信息
3、修改配置文件
然后根据第一版提出问题:
- netty客户端连接了服务端,服务端和客户端是多对一的,那服务端断开连接后,客户端是否都要全部手动重启?
- 是否需要加安全认证,接收操作信息的接口被人知道后,会不会被恶意修改配置文件
- 配置文件不存在怎么办?路径不对怎么办?
此时我们就可以根据第一版提出的问题进行改进。当然安全认证由于时间代价过高,先不在当前需求做。
然后就是第二版:
1、使用netty连接服务端,并且断线后,间隔一分钟一直重连
2、解析接收信息
3、修改配置文件,不存在时返回错误信息
这只是一个简单的需求,所以功能点也很简单的罗列出来了,这个也只是简单分析,如果是更复杂的需求,就再慢慢分析即可。
设计
简单了分析完了之后,就开始我们的面向对象设计了,设计主要就是根据功能点,罗列出我们可能需要创建的类,类中的属性,方法等。
定义类
首先,我们要做的是逐句阅读上面的功能点,拆解成更细化的/更接近类的功能需求,一条一条罗列下来。
1、创建netty客户端的类
2、对客户端进行重连
3、解析netty的io信息(就是netty的channel的双向通信)
4、修改配置文件的类
然后将相同的功能点合并起来,类就设计出来了 如 1和2其实是可以同步做的 创建类为 NettyClient,而第3步为 MessageParser 至于第四步为 DealLogConfig
这是一个初步的类的划分,其他一些不重要的、边边角角的类,我们可能暂时没法一下子想全,但这也没关系,面向对象分析、设计、编程本来就是一个循环迭代、不断优化的过程。根据需求,我们先给出一个粗糙版本的设计方案,然后基于这样一个基础,再去迭代优化,会更加容易一些,思路也会更加清晰一些。
不过,我还要再强调一点,开发需求比较简单,所以,需求对应的面向对象设计并不复杂,识别出来的类也并不多。但如果我们面对的是更加大型的软件开发、更加复杂的需求开发,涉及的功能点可能会很多,对应的类也会比较多,像刚刚那样根据需求逐句罗列功能点的方法,最后会得到一个长长的列表,就会有点凌乱、没有规律。针对这种复杂的需求开发,我们首先要做的是进行模块划分,将需求先简单划分成几个小的、独立的功能模块,然后再在模块内部,应用我们刚刚讲的方法,进行面向对象设计。而模块的划分和识别,跟类的划分和识别,是类似的套路。
定义其属性和方法
类已经基本分好了,之后就是定义类及其属性和方法,后面的话不太想写了,其实就是根据设计模式去定义,以及根据实际需求去定义就好了。比如 DealLogConfig这个类,创建的想法步骤的话就如下:
1、先了解 日志的配置文件的格式是怎样的,然后根据所需要的操作定义属性
2、由于存在新增/修改/删除,此时就可以定义 DealLogConfig为一个抽象类,然后抽出子类 AddLogConfig UpdateLogConfig DeleteLogConfig,然后再用抽象工厂,在接口中根据 操作类型分发子类即可
由于个人能力也一般,无法给出特别好的完整方案,大家知道大概情况即可
备注
有些关于设计的想法想说一下
UML图
之前在设计的时候,特别热衷于画UML图,但是其实UML图也有个弊端,就是箭头类型很多,如果是一个不熟悉UML图的人去看的话,其实会特别辛苦。因为画图也是为了让别人更好的理解。如果只是小组内进行需求开发的话,我建议可以简化,比如直接使用单一的箭头即可,最主要是让人能简单快速的理解到类与类的关系即可。