IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> [Java] 自己写图书馆管理系统(详细版) -> 正文阅读

[Java知识库][Java] 自己写图书馆管理系统(详细版)

目录

一、简介

二、需求

三、具体设计

一、大纲

二、分析过程

三、小结

1.整体流程

2.ListBookOrderByXXXCommand

3.匿名类对象语法知识点

4.类和对象(面向对象设计)

四、完整代码


一、简介


实现一个简单的能对图书馆的书籍进行简单管理的一个系统。所用到的知识有:类,抽象类,封装,继承,多态,接口。(基础知识的学习可看我博客的其他文章~)

二、需求


1.用户登录

2.管理员角色(增加书籍 、查阅书籍(根据书名排序、根据价格排序、根据借阅情况排序)?、删除书籍 、打印书籍列表

3.普通用户角色(查询书籍 、借阅书籍 、归还书籍

都在命令行上完成操作

三、具体设计


一、大纲

1.从持久化存储中(文件)加载书籍信息 -> 以顺序表的形式进行呈现

2.用户登录 -> User对象(多态体现)
3.进入一个循环中
? ? ? ? 3.1打印用户角色对应的菜单,并且让用户选择

? ? ? ? 3.2根据用户的选择,以Executable 对象来体现(多态),执行对应的操作命令(方法最终的执行是由对象类型决定的,对象不同,执行方法不同)
4.用户退出(Ctrl + D),打印退出信息

二、分析过程

1.输入过程需要处理很多事情:①打印提示信息②读取用户输入③用户有没有按 ctrl + D 退出,因此我们直接封装一个对象去处理输入问题。

Input input = new Input();

2.在用户登录中,我们需要一个用户管理的对象,由该对象完成用户登录的具体操作:①要求用户输入②判断用户角色。

 UserStorage userStorage = new UserStorage();
 User user = userStorage.login(input);

3.在打印用户菜单中,我们需要一个接口,可以返回给我们一个可以执行的命令,从输入中打印菜单并且进行用户选择。

IExecutable command = input.menuAndSelect();      //这是一个命令
command.excute(user,input);     //去执行

4.因为我们要写的类很多,所以根据他们不同的职责,进行分类,比如:新建一个输入包把输入的类(Input)放在里面。新建一个用户包,把用户的类(User、UserStorage)放在里面。新建一个命令包,把命令的接口放在里面。

?

5.写 login

①先让用户输入用户名 ②?根据用户名,角色是管理员还是普通用户 ③?根据不同角色,创建不同用户,输入时,写成带有提示的输入(prompt)。

6.在Input 类中完成prompt。

7.我们提前定义好一些用户名,作为管理员。

8.完成IExecutable 接口,里面实现?excute 方法。?

9.完成menuAndSelect()方法,首先要显示菜单,角色不同,拥有的功能不同,因此需要用户信息,把User user 传入。同时menuAndSelect()方法中的showMenu();方法也要实现,首先需要得到这个角色支持哪些命令(以IExecutable[ ] 数组的方式来体现)

    public IExecutable menuAndSelect(User user) {
        showMenu(user); //角色不同,拥有的功能不同,因此需要用户信息
    }

    private void showMenu(User user) {
        //1.得到角色支持的命令
        IExecutable[] supportedCommands = user.getSupportedCommands();
        
        //2.遍历并打印每个命令的名称,显示操作菜单
        for(int i = 0;i < supportedCommands.length;i++){
            IExecutable command = supportedCommands[i];
            System.out.printf("    %2d. %s\n",command.getName());
        }
        
    }

10.想要增加几个命令,就多写几个 command 利用接口、抽象类 + 继承等实现了多态的效果,使得开发的过程变得简单。(分为管理员用户 和 普通用户)

11.具体的实现,添加书籍:1.让用户输入要添加的书籍 input.prompt()? ? ? ? 2.使用用户输入信息,构造成书籍对象Book(name、author、type、price、borrowedBy)? ? ?

public class Book {
    public String name;
    public String author;
    public String type;
    public int price;
    public String borrowedBy;   // 如果没人借走,就是null
}

? 3.把书籍对象添加到类似 BookStorage(书架)对象上。将书籍尾插到书架上

public class BookStorage {
    private Book[] array;
    private int size;

    public BookStorage(){
        array = new Book[20];
        size = 0;
    }

    //尾插
    public void add(Book book){
        //1.确保容量够用
        ensureCapacity();

        array[size++] = book;
    }

    private void ensureCapacity(){
        if(size < array.length){
            //说明至少还可以放一个元素,容量够用
            return;
        }
        //否则进行扩容
        array = Arrays.copyOf(array,array.length * 2);
    }
}

书架对象只有一个,书籍对象有很多个。所以两者之间的关系是容器与元素的关系。把书架抽象成关于书籍的顺序表。

12.实现所有的 command 内容,根据需要也可以添加 command 的内容

13.书籍的格式化:职责归属放到Book.toString()

比较:书籍默认按照名称比较(自然顺序),如果需要其他比较,则使用外部比较器

14.功能实现完成之后,先以管理员的身份运行程序,添加书籍,退出;再以普通用户身份运行程序,借阅书籍;发现普通用户中没有书籍 。如何解决?

借助可以在多进程中共享的存储,这个存储还具有持久化(进程退出后,数据仍然保存)。这个共享的存储就是硬盘:想办法把数据放到硬盘上,硬盘上的数据,被操作系统抽象成一个个文件,我们只需要把数据写到文件中即可

具体实现:1.程序启动时,从文件中(指定一个路径)读取所有的书籍信息,读到内存中(以BookStorage 对象中 Book 的形式体现)

2.凡是对BookStorage 做改动,我们都需要把数据,写一份到文件中(指定路径)

3.规定格式:思考一个Book对象在文件中长什么样?

? ? ? ? 暂且规定:每行一本书,书的属性之间用一个特殊字符(@)分割。这个成立的前提是,书名,作者名,类型名,借阅人的字符中不能出现 \n 和 @,否则不知道怎么去解读了。字符集编码必须是UTF-8。

三、小结

1.整体流程

从持久化存储中(文件)加载书籍信息 -> 以顺序表的形式进行呈现

通过用户登录 -> 当前登录用户对象(管理员用户 or 普通用户)

循环{

? ? ? ? 根据不同的角色用户,显示不同的操作菜单(靠多态机制? <-? 抽象类、继承、引用指向等等这些语法知识点一起来实现)

? ? ? ? 让用户选择具体的操作 ->? 得到当前要指向的命令

? ? ? ? 执行命令,根据命令不同,执行不同的操作(靠多态机制 <-?接口、继承、引用指向等等这些语法知识点一起来实现)

}

对于我们input 对象来说,由于在用户登录、用户选择命令、执行命令时都要用到input 对象,因此,①从性能角度来说,没必要每个地方都建立一个独立的input 对象 ②有时候在代码的不同位置,需要共享一些信息的时候。所以我们有一个公共的input 对象就够了,别人只负责去使用就好了。我们的Input 对象,全局只有一个;User 对象(当前登录用户),全局只有一个BookStorage 对象(图书管理系统的书架)全局只有一个。

2.ListBookOrderByXXXCommand

①模板设计模式:父类(抽象类)实现了 execute 方法:使用操作的模板? ? ? ?

? ? ? ? a.获取外部比较器对象? ?(留给子类们去实现)

? ? ? ? b.获取所有书籍信息

? ? ? ? c.根据比较依据排序

? ? ? ? d.展示列表

多态 为 模板设计模式 提供了底层服务(没有多态,就做不到 模板设计模式)

? ? ? ? 抽象类、继承、方法的重写、引用的指向等语法基础,为实现多态,提供了底层服务

②深入应用了对象的比较 Comparable or Comparator

③代码风格? ? ? ?printBook的代码全部抽象到 Book.toString 中,从面向对象的角度来讲,职责封装更合理。这些代码语句,放到哪里都能执行,但是放到合适的类、合适的方法中,让程序员看起来,层次分明,层次划分的更清楚(封装概念的体现)

④属性对象逃逸(逃逸有风险)

3.匿名类对象语法知识点

public class ListBookOrderByBorrowedCommand extends AbsListBookCommand{
   private static class BorrowedComparator implements Comparator{

       @Override
       public int compare(Object o1, Object o2) {
           Book b1 = (Book) o1;
           Book b2 = (Book) o2;

           int br1 = b1.borrowedBy == null ? 0 : 1;
           int br2 = b2.borrowedBy == null ? 0 : 1;

           return br1 - br2;  //没被借走的比较小,在上面,被借走的在下面
       }
   }

   private final Comparator comparator = new BorrowedComparator();

BorrowedComparator类,这个类,只使用了一次,创建了一个comparator对象。理论上,再也不会用到这个类了。可以用匿名类对象的语法替换,好处:1.不用再花心思为类起名字了。2.从语法角度,保证了确实没有其他地方用到这个类了。3.代码可以短一点。

改进后:

public class ListBookOrderByBorrowedCommand extends AbsListBookCommand{
    private final Comparator comparator = new Comparator() {
       @Override
       public int compare(Object o1, Object o2) {
           Book b1 = (Book) o1;
           Book b2 = (Book) o2;

           int br1 = b1.borrowedBy == null ? 0 : 1;
           int br2 = b2.borrowedBy == null ? 0 : 1;

           return br1 - br2;  //没被借走的比较小,在上面,被借走的在下面
       }
   };

new 父类( ... ) { }; ①定义一个类(没有名字,所以称为匿名类),这个类继承(实现)了父类。②直接用这个类实例化一个对象出来。

4.类和对象(面向对象设计)

输入对象(Input)? ? ? ? ? ? ? ? ? ? ? ? ? 整个应用只需要一份

用户存储对象(UserStorage)? ? ? ?整个应用只需要一份

当前登录用户对象(User:AdminUser、CommonUser? ?也可以添加其他的对象)? ? ?整个应用只需要一份

书架管理对象(BookStorage)? ? ? ?整个应用只需要一份

书籍管理对象(Book)? ? ? ? ? ? ? ? ? ? 用到的时候创建

命令对象(实现了 IExecutable 的很多 XXXCommand 对象)? ? ? ? ? ?理论上:整个应用只需要一份,每个用户子类中独立一份?

四、完整代码


?详情请看:零七/图书馆管理系统https://gitee.com/hlingqi/library-management-system

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-02-09 20:33:44  更:2022-02-09 20:35:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 12:59:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码