0%

java基础阶段图书管理系统项目需求分析过程

2017年7月1日 下午3:16

这篇文章就是我边想问题边写的,记录了我整个思考的过程

几个注意点:
1. 整体的结构要心中有数,可以用图来辅助
2. 这个项目的难点在于功能流程的设计,数据库表的设计很简单
3. 发现隐藏的功能,做好以后功能的扩展。
4. 同时也要学会偷懒技巧,实现简单,但是却让人喜欢

现在想到的功能有:
1. 登陆注册,人员的流动 一天
1. 多用户登陆
1. 一个多线程的服务端
2. 一个客户端
2. 前后端两个
3. 会员管理系统
2. 权限管理系统:
1. 前后端可以设计不同的阶梯,CCF 一天
3. 图书查询系统【核心】: 三天
1. 用户查书有没有,模糊查询
1. 按作者
2. 按类别
3. 按日期查询
4. 按出版社
5. 按库存
2. 用户查自己的借阅情况
1. 用户还书
2. 超时扣钱
3. 管理员
1. 查询一本书的借阅历史
2. 查破损

4. 辅助功能【看时间自由调整】:                                                  一天
    1. 图书的破损,下架,丢失

程序员可以创建类
而用户只能创建对象


老师的那个是权限于功能进行了绑定
而我的这个是权限和功能是分开的,先判断权限再去执行功能。
但是功能从哪来呢?
那还不如最小的权限绑定功能,而角色和权限的多对多功能,这是操作对象,所以能够给了用户来操作,用户和角色的一对多的关系也是对象操作,也可以给了用户


设计模式:

不能为了使用设计模式,专门去向哪里可以用,
功能为导向哦!



这里的额priority1-3不能出现方法的重名

为了以后扩从管理员的功能:这里使用了代理模式
priority1是priority3针对interface3种方法的扩充
interface1,interface2是横向扩充
interface3 是纵向扩充


如何实现一个权限分多级的情况?

在interface中写不同的方法e.g.:input1() input2()
这里的权限1,2就是权限等级
这里的核心问题就是方法的参数化:利用反射可以解决
使用方法:
User中有一个方法userMethod(String methodName);
实现类似于:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 反射中方法的测试
import java.lang.reflect.Method;

public class Test_Method {
public static void main(String[] args) throws Exception{
//获取Student对应的Class对象
Class cla=Student.class;
//创建Student对象
Student p=new Student();
//得到setName方法
Method met1=cla.getMethod("setName", String.class);
//调用setName,为name赋值
met1.invoke(p, "Jack");

//得到setName方法
Method met=cla.getMethod("getName", null);
//调用setName,为name赋值
Object o=met.invoke(p, null);
System.out.println(o);
}

}

其实这里可以使用组合模式
将Role继承自priority
好处是:要是用户只有一个Priority,一步就可以完成了,省去了Role。


如何实现上下级批准:

这个不属于类的设计,是通过逻辑代码实现的。
要是在类图中就实现上下级,那是一定不可改变得。

以及实现人员的变动,这都是通过逻辑代码实现的。


服务端的任务—其实是个假的服务端,因为他仅仅完成了登陆这一个功能:

1. 服务端就是一个黑盒
2. 不走权限整个流程
3. 接收的是用户名和密码
    1. 实现判断
    2. 实现注册
4. 返回的是
    1. 登陆是否成功
    2. 注册是否成功
    3. Flag标志区分普通用户和管理员
5. 实现普通用户和管理员的区分
    1. 查不同的文件txt

客户端:

1. 拿到用户名密码
2. 给了服务器
3. 根据服务器的返回,执行不同的普通用户和管理员的方法
4. 运行不同的操作(界面)

如何确定当前用户的操作?并执行?

现在是像洋葱一样,一层一层的,要用的对象(priority对象)在最里面。
User的useMethod()方法中的Class.from()这里写啥?
如果要是表中:用户 <—>priority
那Role怎么办?
Role是程序写的,这里就要实现其中包含的priority的全部方法。

啥是活的啥是死的?

程序员:
1. 增加一个priority类别,增加一个role类别
用户:
1. 在当前已有的priority 和 role中进行选择

又绕回到了一开始的那就话:

用户是不能去创建一个类,或者创建一个类中的方法的。
这些都是程序写死的,用户最多只能选择!


人工智能


能不能先写逻辑,再写图形界面?

1. 数据获取的方式发生改变。
    1. 原来是scanner
    2. 现在是JFrame的txt框
2. 页面跳转的方式放生了变化
    1. 原来是输入数字选
    2. 现在是鼠标点
3. 数据的输出方式了改变
    1. 原来是printf
    2. 现在是JFrame中

总体来说:填了很多麻烦

先写逻辑,后写图形

类有哪些?

1. 上面的权限,一堆
2. 还有book,bookBiz
3. 文件操作的FileBiz

有哪些包?

1. entity.book
    1. 计算总价方法
    2. 显示图书信息方法
2. bookBiz
    1. 初始化书的信息
    2. 图书入库
    3. 图书出库
    4. 新增图书
    5. 查询图书
    6. 购买图书
    7. 查询图书是否存在
3. entity.user
    1. 从priority获取方法名数组【长度规定为10】
    2. 显示当前用户所具有的功能
    3. 建立数字和方法的对应关系
    4. 根据输入,通过反射调用不同的功能
    5. 这里的输入之后,还得进行一个字符串拼接,实现权限分级
4. priority
    1. 调用bookBiz
    2. **获取方法名的数组**
5. priority.ext
6. priority.impl
7. file
8. file.impl
    1. 获取一行数据
    2. 取一行数据,分割到数组
    3. 取全部的数据,保存数组,除了第一行
    4. 插入表头
    5. 插入一条数据
    6. 新建一个文件
9. Test
    1. 给client数据
    2. 调用user完成工作
10. Server
    1. Thread
    2. 干活的类
11. Client
    1. 从test拿到数据给server

步骤?

1. 文件
2. book
3. 权限
4. server
5. user
6. test

把这个权限打成一个jar包去使用
这个现在还不考虑


权限

我知道的:
1. 类名
两种解决方法:
1. 给User建子类,每回登陆通过判断类名,好多的if产生不同的对象
1. 每次增加一个类,都要两边写
2. 试用反射,用类名 把类先反射出来(通过反射来读类
1. 这时已经能调用方法了
2. 能调用方法,那所有的问题都解决了


新的问题

1. **方法知道了,但是参数不知道**
    1. 在写一个参数的方法
    2. 其重要有参数的个数 和 类型
2. **invoke返回的是object对象**,除了string 和 int 类型
    1. 其他的类型是固定的没几种
        1. string[]
        2. string[][]
        3. ArrayList<String>

三个方法返回数组中的内容是有顺序的,必须一致
这个可以抽象成一个方法
3. 如何融入权限分层
1. 要限定
1. 一共三层
2. 方法要用method_1(),method_2();固定的_来分割
3. 把取出来的方法分割

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Class c=Class.forName("cn.chenzhiheng.user.priority.PriorityClient");
Object o=c.newInstance();
Method[] m=c.getMethods();
for(int i=0;i<m.length;i++){
System.out.println(m[i].getName());

if(m[i].getName().equals(method)){
Object[] os=new String[1];
ArrayList<String> strings=(ArrayList<String>) m[i].invoke(o,null);
for(int j = 0 ;j < strings.size();j++){
System.out.println("***"+strings.get(j));
}
}
}

Test的操作流程

1. scanner **获取用户名和密码+userId**
2. 通过client传递给server
    1. 这里要区分增删改查
3. 接受server传递过来的用户权限
    1. 不一定是权限
    2. 有可能是操作是否完成
4. 根据用户权限调用user打印出当前所有的方法
5. 调用方法去完成一些操作

当加上界面的时候

1. 界面是点的操作
2. 而控制窗是从上到下的一个顺序操作
3. 所以,**控制窗与逻辑的交互**由一个分割好的**test来完成**

三个数据表增删改查之间的关系

1. 买书的时候要增加info
2. 不删除book和user 只更改他们的状态
3. 退货删info
    1. 输入infoId
    2. 通过infoid找到bookid
    3. 删除info
    4. 更改bookid对应的数量
4. **user_book不直接操作,全部由Book类来操作**

怎样实现自增

1. 抽象类 static index
2. index++;
3. 构造函数

权限的升级:

1. 已有权限
    1. 直接更改用户的priority字段
    2. 用户权限的更改只能有管理员进行
2. 没有的权限
    1.有可能 **写Biz**
    2. 写priorityImpl
    3. 写priority继承自 ext 实现impl接口
    4. 然后在写一个role在包括原来的和现在的对象
    5. 在像上面一样更改用户权限字段

Biz的功能不是priority 都必须用了e.g.:insertHead。
程序员用一次就行了


这回幸亏是从下往上做,每一层都是一个封装。
对下层的多次运用


如何拿到使用不同类型反射回的结果

1. 由于多态中不支持多返回的类型
2. 所以这种情况,只能写不同的方法

结算功能:
一个用户-一个权限-一个Userbiz(多个唯一的biz)


理想中的代码层次-应该像:MVC
1. 我从数据库中取出用户的权限等级,作为全局变量
2. 然后生成对应这个等级的页面
3. 点击一个功能按钮,然后跳到逻辑处理层
4. 逻辑处理层的数据,然后投影到一个页面中
5. 页面—>跳到逻辑层—>新的页面
6. 就像TP一样
现在:
1. 我点击功能按钮,然后逻辑处理
2. 逻辑处理完,显示到页面
3. 这个整个过程是瀑布型的,像c一样从上到下的执行
4. 没有跳转
5. 页面—>走逻辑—>旧页面
6. 就像原生php一样


那么第二种为啥会把一个权限系统给废了?

1. 这的权限系统就是一个**逻辑层**
2. **入口**的是你要执行的**方法名**
3. **出口**是你要的**数据**
4. 这就一个**封装**
5. 不是废了,**我这个权限系统不是用来分层的**

假设你现在已经按不分层的想法写完了项目,那么有啥改进的地方?

1. 现在的情况,就是JFrame其实就是再次把UserReflectf封装了一次
2. 如果让增加功能,不仅权限里要增加相应的类,而且还要更改对应的页面
3. 做的这个权限系统不是让权限完全随用户更改添加,而是更重要的是**程序员做维护的时候好维护,自己用这个权限写项目思路更加清晰**
4. 如果是分层写的话,会这样思考
    1. 页面用不用改?哪里改?眼前全是html
    2. 逻辑用不用改?哪里改?眼前全是php逻辑
5. 如果不是分层写的话,会这样思考
    1. 乱死了,这个不是页面,跳过/这个不是逻辑,虽然明显,但是时间长了自己会**烦躁**。
6. **关键:**分层写,我可以在逻辑层处理多种任务,获得多次的数据,然后把**多组数据**都传递给新的页面
7. 分层于不分层的直观理解:
    1. 分层是把不分层的中写在**一个页面的所有过程**,集中放在一个新页面中,是一个**提取的关系**
    2. Ps:相似的功能可以通过将**各个过程封装到成方法中**
8. **分层知识为了更清晰,没其他作用**

我用反射实现的权限管理

1. 本质是实现了一对多的关系,**就是一个封装而已**
    1. 反射解决的是字符串产生对象的这个过程
    2. 一个字符串,就能对应那么多的具体的权限功能
2. 但是在这个项目中界面中只能是一对一的关系
    1. 一个界面已经绑定了一个代表权限的字符串了
3. 那这个权限系统在哪里才可以发挥它最大的作用
    1. 权限可以无限多
    2. 增加起来方便
    3. 一个权限功能的实现
        1. 权限名
        2. 方法名+参数
        3. 2这个是必须的,并不是我这个系统设计不合理留下的小尾巴
    4. 可以使用字符串直接对应权限,更加方便,直观(不用用数字去表示了)
    5. 总结:**因为封装好了,以后程序员用起来就比较方便了**
        1. 对用户来说,屁用没有
        2. 对程序员来说,却是极大的方便
    6. 这就是写框架要站的角度,和写项目占的角度**对比**
        1. 写框架是为让程序员更加爽、简单,框架就是一个封装,把麻烦的事情封装到一个黑盒中,然后,留一口,然程序员简单做到。在这过程中,程序员不用懂得其中的道理。
        2. 写项目时想的是如何实现一个功能,常常就为了一个boss功能较劲脑汁
        3. **但是**,顶尖的程序员,**做出项目来估计和设计框架是一样的**

关于接口再说两句

1. 我突然一下感受到了接口的好处
    1. 在一开始,我写底层一个最小单位的一个书籍管理权限,其实直接创建一个类,写方法,填注释就行了。这时写接口是一件麻烦的事情。
    2. 但是,当我从底层越来越向上封装,集成。这时,我如果想在其他类中说明也要使用这些方法,我只要加上对应的接口,方法自动出来,我填内容就行。一般来说,内容可以直接用底层的对象调用来实现
    3. 如果没有接口,我就得反复的回去看底层的具体的类实现。还生怕拉下一个。
    4. 最常用的地方是:当修改一个,增加一个功能时,接口可以方便的提醒你还有哪些地方要改。对你的操作有**指示作用**
    5. 有时候需要去写一个抽象类,但是,java本身的这个类中就有继承如JFrame继承自Frame,这时只能用接口来救急了。
    6. 用了接口,妈妈在也不用为我担心这个问题了。

我现在是站在一个写框架的角度去思考
但是,这也回答了一个问题我们看框架的时候会经历什么
最终,当你看完一个框架的时候,你脑子中是有一副类图的
like:


退书和总价的关系?

Index还是有问题
Table
1. 不初始化初始化
2. 覆盖


监听实现接口写在一起的好处

1. 可以何在一起写逻辑,而,单个是时候互不影响

如何能发挥出这个权限系统的最大能力

1. 数据库中用户的权限是一个**对应权限类名**的一个字符串
2. UserRflect的参数就是**权限字符串**
3. 然后就可以通过UserRflect来调用**对应权限类**下的方法
4. 能够去除当前权限下的所有方法,但是这些方法并不是简单地像输出不同的语句这样的**不需要任何输入,有统一输出的的方法**,所以不能做统一的界面去执行所有的功能。
5. 就像web中的导航栏,导航栏可以是统一的,但是导航栏连接到的每个单独不同的页面,**这得一个一个的做**。

如何让这个权限系统能够自动识别权限等级

1. 如果实现了能够自判等级大小
    1. 那么在做相关功能的时候只需要调用一个方法就可以实现
    2. 比如说我这里要实现**当前用户只能看权限比他低的人的信息**
    3. 这个函数的参数是**权限字符串1 权限字符串2**
    4. **返回boolean**
2. 另一种实现方式,在biz查询全部用户的时候,在这就判断出结果。
    1. 那么,这种实现方式就和权限系统没关系了
    2. 如果在biz中在声明userRflect。
        1. **userRflect是用来执行方法的,不是用来判断权限的!**
    3. 那么,可以再设计一个userRflect配套的类,参数和返回值像1所说的。
3. 现在方案定了,就差功能的实现了!
    1. 如何才算是权限大,有哪些情况
        1. 存在**包含关系**的时候能判断权限大小
            1. 第一种:一个role中包含了多个priority,那么这些priority都比这个role权限小
            2. 第二种:role1包含role2时,role1的权限大于role2 的权限。
            3. 循环嵌套
    2. 那么问题来了,如何**判断他们的包含关系**
        1. 组合关系的递归
4. **一下午!实现了**
5. 使用方式:
1
2
Compare compare = new Compare();		
boolean flag = compare.compare("priority.PriorityBaseBook", "role.RoleAll");

我这个系统里面priorit对于图书的和用用户的管理都分别设置的普通给用户client端和管理员manager端,这是不符合实际的

因为
1. 现实中,manager和client等级一高一低
2. 但是在priority包中定义的权限他们是没有高低的,都是一个独立的权限
怎么改:
1. 将priority包下的manager接口方法移动到role包下的对应的manager接口中,
2. 然后在role包下的实体类中重新实现接口中的方法
3. 对于role下包的实体类来说,是没有影响的
4. 因为,他implments 多个接口,我们现在只是把一个接口中的方法放到另一个接口中,对role实体类来说无视


循环包含的时候
1. 接口要自己去查基础功能的接口,可以直接从包含类implement中复制过来
2. 返回的方法和返回值类型也可直接拷贝,修改下长度


这个权限系统使用的要求:

1. 名字 属性名两部分  类名前准
    1. Priority包下,都是以priority为开头
    2. Role包下都已role开头
    3. 这个为了实现**权限等级判断的必要条件**
2. 方法 实例化哪几个方法
    1. PriorityExt抽象类下
        1. getReturns
        2. getMethods
    2. RoleExt extends PriorityExt
        1. getInclude
        2. **注意:role方法+1 judge**
3. 使用方式 
    1. 只需要一个**权限字符串**
4. 不同位置概念上的区别 
    1. Priotity包下,都是**最小单位的权限**,**并且不包含**,各为独立的个体
    2. Role包下,**可以不包括priority**,单独成为个体,作为最小单位。但是不同的是,**可以成为包含关系**

权限系统的完整包


最后要做的工作

1. 表格实现信息修改—完成
2. 管理员图书出库做判断—完成
3. 用户查无此id的
4. 退书应该加上专门的一个现实的表,然后进行点击退书
5. 注册用户的验证
6. 标题

如何学习table,如何了解table如何使用,他又那些功能。

1. 即使是别人写好的,你也不一定会用!
2. 手册的重要性,这个过程中一定会看大量的文档。
3. 文档的写法基本上也是按照一个个功能,**问题为主导的**。
4. 方便读者寻找自己想要的功能。
5. 这与我写文章的思路正好相符
6. 在这个过程中,有一个很大的问题就是**如何知道有什么功能**,以及会**涉及到其他**的什么类,接口,抽象等等
7. **如何实现其实不是最难的**,**手册**能解决这个问题,但是上面一个问题手册不一定能明显的解决。

table_3.addTableModelListener(this);
就像我不知Jtable中model这个东西一样


这回的文件封装的和屎一样

/*
* 这里应该是通过当前用户的权限去更改User.txt文件中的数据
* 但是我在client的接口中没有实现这个方法
* 现在不带了改了
* 所以就直接跳级
* 用底层封装好的文件操作改了
* 这样做是不对的!!!!!
*/


问题才是一个系统设计的核心!!!!