【JavaSE】综合练习(图书馆管理系统附链接)

目录

一、目的

二、任务

三、设计思路

四、基本框架

五、实现细节

六、总结


一、目的

利用前面所学的知识点:类,抽象类,封装,继承,多态,接口等进行的一个简单的代码练习。

二、任务

1、简单的登录

2、管理端

添加书籍、删除书籍、按名称排序、按价格排序、按借阅情况排序、退出

3、用户端

按名称排序 、按价格排序、按借阅情况排序、借阅书籍、归还书籍、退出

三、设计思路

        我们首先需要一个Main函数来作为我们程序执行的路口。Main中首先需要完成用户的登录过程,然后进入循环,打印出用户的可选择项目,然后根据用户的输入来执行相应的操作。

        首先我们可以将图书抽象成为一个类,然后用一个书架来记录这些书对象的信息,我们需要将信息写在文件中,每次运行时需要将文件信息加载到对象中。

        我们可以将输入封装为一个类。这个类需要有一个(prompt)方法来返回用户的输入信息。还需要借助这个方法以及打印菜单的(showMenu)方法完成对用户的选择执行相应的操作的方法。

        因为输入的用户有两种类型,我们定义一个抽象类来供具体的用户类来继承。我们还可以额外定义一个类来完成用户的登录,以及管理员用户的判断。

        完成登录操作之后就需要进入循环完成对应用户的功能了,我们可以将用户的功能用一个接口实现,然后执行对应的操作。

四、基本框架

        以下是主函数的设计,只需要看框架,所以省略了包的导入,(整体代码贴在文末)

public class Main {
    public static void main(String[] args) {

        //0.实例化一个负责处理输入的对象
        Input input=new Input();
        //改成从文件中来加载数据
        BookStorage bookStorage = BookStorage.loadFromFile();

        try {
            //1.用户登录
            //1.1需要一个用户管理对象完成登录的具体操作
            UserStorage useerStorage=new UserStorage();
            //1.2判断用户角色
            User user=useerStorage.login(input);


            //2.进入循环
            while(true){
                //2.1打印用户的菜单,斌且让用户选择
                //用一个接口来体现这种能力
                IExecutable command=input.menuAndSelect(user);
                
                command.execute(bookStorage,user,input);
            }
        }catch (QuitException exc){

        }
        //3.用户退出
        System.out.println("欢迎下次使用!!!");
    }
}

input类的框架

public class Input {
    private final Scanner scanner= new Scanner(System.in);

    public String prompt(String prompt) throws QuitException {
        //此部分用于返回输入信息
    }

    public IExecutable menuAndSelect(User user) {
        //此部分要根据用户对象读取其支持的功能,然后打印出可选择菜单,然后让用户做出选择
        while (true){
            //1.需要得到这个角色支持那些命令
            IExecutable[] supportedcommands=user.getSupportedComands();

            showMenu(supportedcommands);

            String selectStr=prompt("请输入您的选择");
            try {
                int select = Integer.parseInt(selectStr);
                if(select>=1&&select<=supportedcommands.length){
                    return supportedcommands[select-1];
                }
                System.out.println("请输入正确的序号");
            }catch (NumberFormatException exc){
                System.out.println("请输入正确的数字");
            }
        }
    }

    private void showMenu(IExecutable[] supportedcommands) {
        //此部分需要协助上部分打印菜单
        for (int i = 0; i < supportedcommands.length; i++) {
            IExecutable command=supportedcommands[i];
            System.out.printf("    %2d. %s\n",i+1,command.getName());
        }
    }
}

UseStroage类的框架

public class UserStorage {
    private static final String[] ADMIN ={
            //此部分记录管理员的信息,可用于比对
    };
    public User login(Input input) {
        //调用input中的方法来完成登录,并且根据用户输入的信息返回不同的用户类的对象
    }
    private boolean isAdmin(String username) {
        //用于协助判别是否管理员
    }
}

 user抽象类

public abstract class User {
    private String username;    //记录用户名称
    public User(String username) {
        this.username = username;    //构造方法
    }
    public String getUsername() {
        return username;            //读取用户名方法,方便后续操作
    }
    public abstract IExecutable[] getSupportedComands();    //读取用户支持的指令

}

普通用户类

public class AdminUser extends User {
    public AdminUser(String username) {
        super(username);
    }

    @Override
    public IExecutable[] getSupportedComands() {
        //此操作是为了得到IExecutable[]列表,其中每个元素为实现了IExecutable的类。
        return new IExecutable[]{
                new AddBookCommand(),
                new RemoveBookCommand(),
                new ListBookOrderByNamecommand(),
                new ListBookOrderByPriceCommand(),
                new ListBookOrderByBorrowedCommand(),
                new Quite()
        };
    }
}

管理员用户类 

public class CommonUser extends User {
    public CommonUser(String username) {
        super(username);
    }

    @Override
    public IExecutable[] getSupportedComands() {
        return new IExecutable[]{
                new ListBookOrderByNamecommand(),
                new ListBookOrderByPriceCommand(),
                new ListBookOrderByBorrowedCommand(),
                new BorrowOperation(),
                new ReturnOperation(),
                new Quite()
        };
    }
}

IExecutable接口,用于命令的实现

public interface IExecutable {
        void execute(BookStorage bookStorage, User user, Input input);//用于执行具体操作
        String getName();//便于打印命令信息
}

book类

public class Book implements Comparable {
    public String name;
    public String author;
    public int price;
    public String type;
    public String BorrowedBy;

    @Override
    public int compareTo(Object o) {
        Book b=(Book) o;
        return name.compareTo(b.name);
    }

    @Override
    public String toString(){
        String s=String.format("书名:《%s》 作者:%s 价格:%d 类型:%s ",name,author,price,type);
        StringBuilder sb = new StringBuilder(s);
        if(BorrowedBy==null){
            sb.append("没有被借走");
        }else{
            sb.append("被 ");
            sb.append(BorrowedBy);
            sb.append(" 借走了");
        }
        return sb.toString();
    }

    public boolean isBorrowed() {
        return BorrowedBy!=null;
    }

    public boolean equalsByName(String name) {
        //为了封装写成了这样
        //name属于String类型,需要equals判断。
        return this.name.equals(name);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Book book = (Book) o;
        return name.equals(book.name);
    }

    public void borrow(User user) {
        BorrowedBy= user.getUsername();
    }

    public boolean isBorrowedBy(User user) {
        if(this.BorrowedBy==null){
            return false;
        }
        return this.BorrowedBy.equals(user.getUsername());
    }

    public void returnBook(User user) {
        this.BorrowedBy=null;
    }
}

BookStorage类

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

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

    private static final File file=new File("此处为文件路径");

    public static BookStorage loadFromFile() {
        //读取文件
    }

    public void add(Book book){
         //尾插
    }

    private void ensureCapacity() {
        //扩容
    }

    public Book[] toArray() {

    }

    public Book searchByName(String name) {

    }

    public void remove(Book book) {

    }

    public void saveToFile() {
        //将文件保存
    }
}

思考:整体的框架如上,其中很多类的方法都是在实现的过程中为完成指定功能而添加的。我们大致整理一下思路。

        首先程序开始运行,new一个input对象用于输入,然后调用BookStorage中的静态方法loadFromFile()来读取文件信息,返回一个bookStorage对象。然后new一个useStorage对象调用对象的实例方法login(input)传入input对象,然后在login中调用prompt()方法,然后根据输入new出user对象并且返回。

        然后进入循环,调用input的menuAndSelect(user)方法,传入user对象。在该方法中,调用user的实例方法getSupportedComands()返回一个IExecutable[]类型的supportedcommands对象

,然后执行showMenu(supportedcommands)打印出可执行的信息,然后调用prompt()方法读取用户输入的信息,然后最终返回对应操作的对象command。

        最后执行该command对象的execute(bookStorage,user,input)方法。这些方法就是我们需要具体完成的功能(我们用一个接口IExecutable来供这些类来实现)。

五、实现细节

        其中有三个功能是排序这些书籍,于是我们可以用一个抽象类来完成,并且可以通过重写比较器的方法来来完成排序。

抽象类的代码:

public abstract class AbsListBookCommand implements IExecutable{
    protected abstract Comparator getComparator();

    @Override
    public void execute(BookStorage bookStorage, User user, Input input) {
        Comparator comparator=getComparator();
        Book[] books=bookStorage.toArray();
        if(comparator==null){
            Arrays.sort(books);
        }else{
            Arrays.sort(books,comparator);
        }
        for (Book book : books) {
            System.out.println(book.toString());
        }
        System.out.println();
        System.out.println("排序完成");
        System.out.println();
    }
}

其中一个排序功能的实现:

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 borrowed1=b1.BorrowedBy==null ? 1:0;
            int borrowed2=b2.BorrowedBy==null ? 1:0;
            return borrowed2-borrowed1;
        }
    }
    private final Comparator comparator=new BorrowedComparator();
    //BorrowedComparator只使用了一次,可以用匿名类来实现。在此不作展示
    @Override
    protected Comparator getComparator() {
        return comparator;
    }
    @Override
    public String getName() {
        return "按借阅情况排序并列出";
    }
}

         添加书籍:按要求输入书籍信息,然后new一个book对象并且初始化,然后尾插到bookstorage对象中。

         删除书籍:按要求输入信息,查找到该书的下标,将最后一本书移到该书的位置,然后让最后一本书设为null然后size--。

        借阅书籍:将book的BorrowedBy属性设置为user的名字。

        归还书籍:将book的BorrowedBy属性设置为null。

以上4个操作都需要将信息保存到文件中。

六、总结

        以上部分可以对我们的基础知识做一个回顾。还需要熟悉这种模板设计模式,并且使用这种面向对象的编程思想。

代码链接

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值