Java面对对象类设计随笔
程序员文章站
2022-03-05 17:24:18
...
想要做好设计很不容易,类、接口和模块设计都是一项高难度的工作。在网上也看过很多的总结,这里我就结合前人和我自己的想法,提一下大概我做类设计的步骤:
1、先需求设计理清整个系统或者整个模块、组件做什么的,就好比现在要开办一家企业,这家企业要做哪方面的业务;
2、再按功能分包,包的职责尽可能的单一,就好比现在公司开始好,要开始划分公司组织结构了,有销售部、人事部、行政部、内控部、研发一部、研发二部等等,部门的职责单一,由于研发的目标不同,研发部门也应该细分;
3、 定义类的职责,一个类的职责就是这个类存在的价值,若你不能清晰的给这个类定义职责,那么很可能意味着这个类没有存在的价值。类的职责尽可能的单一,这样以后变化的可能性也是单一的,类可变性越小,修改这个类的机会就越小,从而提高了维护性和减少Bug。这时候类就相当于部门中的岗位,而对象就相当于人。
4、 定义类的名称,找个好名字来作为类名,通过该名称基本能知道该类的职责。好名字的标准就是用名字表达意图,首先他得有意义,如果找不到有意义的名称来定义,那只能说明类的职责没定义好。一般我们用英文名词来作为类的名称,就像converter就比convert好;
5、 面向接口设计,像Spring的设计一样,尽可能的通过实现接口去设计,把公共方法集抽成接口,接口应该具备完备方法且无冗余方法(当然也有例外,有时候为了提高类的便利性会有一些冗余方法)。接口的好处就在于接口和实现分离,抽象化,在一个方法需要有很多实现的情况下,接口是能体现出好处的,坏处就是设计的难度变大了,设计阶段接口没设计好,之后接口变了,实现也就乱了。在我理解,接口就相当与企业组织结构中的角色,比如公司中岗位可能只有研发工程师,没有细分设计师、dba、需求分析师,那后者就是所谓的角色,也许这个概念有些牵强,我这么说也只是为了能理解而已。
6、 后面两步其实都不是在设计阶段了,已经是实际开发中需要做的事情了,但是也是要提前想好的;
7、 编写类的规范,可以用javadoc来做,这部门在赶工的情况下经常被忽略。
8、 编写单元测试来使用自己的接口。这里就很好的促使TDD开发的办法。我自己做开发的时候是很喜欢先写单元测试,通过不断的排除单元测试的Failed ,接口与实现类就慢慢的都敲出来了。
另外,需要注意的有几点细节,也基本是学java的都知道的:
1、 设计类的时候,封装、信息隐藏这些都是面对对象设计的规范,注意就好了;
2、 接口的命名、类的命名有一致性,比如接口用I开头,控制类用 xxxcontroller,服务类是xxxservice等等;
3、 不要在一个类中使用太多的基础类型,如果基础类型太多,则根据职责功能去封装成一个新的业务对象类;
4、 这次的项目我们准备采用Rest-ful架构,所以API的设计也很关键。好的API,应该是扩展性好,容易被复用。等之后完工,应该会把这块单独拿出来。
既然说到类设计,那也把基础的UML中的类关系顺带提一下。
类间关系有很多种,在大的类别上可以分为两种:纵向关系、横向关系。
纵向关系就是继承关系,它的概念非常明确,也成为OO的三个重要特征之一,这里不过多的讨论。
横向关系较为微妙,按照UML的建议大体上可以分为四种:
1. 依赖 (Dependency) :虚线 + 箭头
2. 关联 (Association) :实线 + 箭头
3. 聚合 (Aggregation) :空心菱形 + 实线 + 箭头
4. 组合 (Composition) :实心菱形 + 实线 + 箭头
它们的强弱关系是没有异议的:依赖 < 关联 < 聚合 < 组合。然而它们四个之间的差别却又不那么好拿捏,需要好好体会。
这里就简单的说一下。
依赖就是use a的关系,就是一个类的函数中使用到了另个类,而不对该类进行持有。
关联就是长期持有对象的引用,而且这种关系可以是相互的。当要结束这种关系,只要双方同意就可以结束。好比朋友,你有一个朋友的集合,你也这是他朋友集合中的一个,当你们发生矛盾了,你们可以断开这个引用关系。
聚合是强版本的关联。被聚合的对象还可以再被别的对象关联,所以被聚合对象是可以共享的。虽然是共享的,聚合代表的是一种更亲密的关系。比如家,可以和你妻子共享,但是你不会随意给朋友共享,而且关系不是相互的。
组合是关系当中的最强版本,它直接要求包含对象对被包含对象的拥有以及包含对象与被包含对象生命期的关系。比如心脏。
1、先需求设计理清整个系统或者整个模块、组件做什么的,就好比现在要开办一家企业,这家企业要做哪方面的业务;
2、再按功能分包,包的职责尽可能的单一,就好比现在公司开始好,要开始划分公司组织结构了,有销售部、人事部、行政部、内控部、研发一部、研发二部等等,部门的职责单一,由于研发的目标不同,研发部门也应该细分;
3、 定义类的职责,一个类的职责就是这个类存在的价值,若你不能清晰的给这个类定义职责,那么很可能意味着这个类没有存在的价值。类的职责尽可能的单一,这样以后变化的可能性也是单一的,类可变性越小,修改这个类的机会就越小,从而提高了维护性和减少Bug。这时候类就相当于部门中的岗位,而对象就相当于人。
4、 定义类的名称,找个好名字来作为类名,通过该名称基本能知道该类的职责。好名字的标准就是用名字表达意图,首先他得有意义,如果找不到有意义的名称来定义,那只能说明类的职责没定义好。一般我们用英文名词来作为类的名称,就像converter就比convert好;
5、 面向接口设计,像Spring的设计一样,尽可能的通过实现接口去设计,把公共方法集抽成接口,接口应该具备完备方法且无冗余方法(当然也有例外,有时候为了提高类的便利性会有一些冗余方法)。接口的好处就在于接口和实现分离,抽象化,在一个方法需要有很多实现的情况下,接口是能体现出好处的,坏处就是设计的难度变大了,设计阶段接口没设计好,之后接口变了,实现也就乱了。在我理解,接口就相当与企业组织结构中的角色,比如公司中岗位可能只有研发工程师,没有细分设计师、dba、需求分析师,那后者就是所谓的角色,也许这个概念有些牵强,我这么说也只是为了能理解而已。
6、 后面两步其实都不是在设计阶段了,已经是实际开发中需要做的事情了,但是也是要提前想好的;
7、 编写类的规范,可以用javadoc来做,这部门在赶工的情况下经常被忽略。
8、 编写单元测试来使用自己的接口。这里就很好的促使TDD开发的办法。我自己做开发的时候是很喜欢先写单元测试,通过不断的排除单元测试的Failed ,接口与实现类就慢慢的都敲出来了。
另外,需要注意的有几点细节,也基本是学java的都知道的:
1、 设计类的时候,封装、信息隐藏这些都是面对对象设计的规范,注意就好了;
2、 接口的命名、类的命名有一致性,比如接口用I开头,控制类用 xxxcontroller,服务类是xxxservice等等;
3、 不要在一个类中使用太多的基础类型,如果基础类型太多,则根据职责功能去封装成一个新的业务对象类;
4、 这次的项目我们准备采用Rest-ful架构,所以API的设计也很关键。好的API,应该是扩展性好,容易被复用。等之后完工,应该会把这块单独拿出来。
既然说到类设计,那也把基础的UML中的类关系顺带提一下。
类间关系有很多种,在大的类别上可以分为两种:纵向关系、横向关系。
纵向关系就是继承关系,它的概念非常明确,也成为OO的三个重要特征之一,这里不过多的讨论。
横向关系较为微妙,按照UML的建议大体上可以分为四种:
1. 依赖 (Dependency) :虚线 + 箭头
2. 关联 (Association) :实线 + 箭头
3. 聚合 (Aggregation) :空心菱形 + 实线 + 箭头
4. 组合 (Composition) :实心菱形 + 实线 + 箭头
它们的强弱关系是没有异议的:依赖 < 关联 < 聚合 < 组合。然而它们四个之间的差别却又不那么好拿捏,需要好好体会。
这里就简单的说一下。
依赖就是use a的关系,就是一个类的函数中使用到了另个类,而不对该类进行持有。
关联就是长期持有对象的引用,而且这种关系可以是相互的。当要结束这种关系,只要双方同意就可以结束。好比朋友,你有一个朋友的集合,你也这是他朋友集合中的一个,当你们发生矛盾了,你们可以断开这个引用关系。
聚合是强版本的关联。被聚合的对象还可以再被别的对象关联,所以被聚合对象是可以共享的。虽然是共享的,聚合代表的是一种更亲密的关系。比如家,可以和你妻子共享,但是你不会随意给朋友共享,而且关系不是相互的。
组合是关系当中的最强版本,它直接要求包含对象对被包含对象的拥有以及包含对象与被包含对象生命期的关系。比如心脏。
上一篇: 面向对象OO编程基础
下一篇: Java中接口的使用方法简介
推荐阅读
-
Java面向对象(1)面向对象的思想概述以及类的介绍,封装和构造方法
-
面对对象设计4——实战销售业绩管理系统
-
面对对象--对象和类
-
Java JDBC入门之八 : DAO设计模式重构查询方法 AND 使用BeanUtils工具类操作JavaBean
-
Java之反射第十八天( --反射----类的加载--获取对象属性( 成员变量和方法)-- 构造方法 )
-
浅谈java面向对象(类,封装,this,构造方法)
-
透彻理解Java中Synchronized(对象锁)和Static Synchronized(类锁)的区别
-
浅谈java面向对象(类,封装,this,构造方法)
-
如何理解Java中基类子对象的构建过程从"基类向外"进行扩散的?
-
关于Java跨域Json字符转类对象的方法示例