图书管理

来源:互联网 发布:php 输出json 编辑:程序博客网 时间:2024/06/03 00:54

package day5;

import java.io.BufferedReader;  

import java.io.IOException;  

import java.io.InputStreamReader;  

import java.text.SimpleDateFormat;  

import java.util.*;  

   

/** 

 * 一个图书馆的课程设计。主要功能: 

 * 1. 创建图书 

 * 2. 创建读者 

 * 3. 借书 

 * 4. 还书 

 * 5. 列出所有书 

 * 6. 列出已借书 

 * 7. 列出超过日期未还的书 

 */  

public class LibrarySimulator {  

   

    // 主菜单  

    private static final String MAIN_MENU = "1. 列出所有的书/n" +  

            "2. 列出已借出的书/n" +  

            "3. 列出过期未还的书/n" +  

            "4. 列出所有读者/n" +  

            "5. 创建图书/n" +  

            "6. 创建读者/n" +  

            "7. 借书/n" +  

            "8. 还书/n" +  

            "9. 退出/n" +  

            "请输入序号:";  

   

    // 选择图书类型的菜单。在借书和添加图书的时候都会用到  

    private static final String TYPE_MENU;  

   

    // 表示一个数字的正则表达式  

    private static final String DIGIT_CHOICE_PATTERN = "^//d$";  

   

    // 表示非空字符串  

    private static final String NOT_EMPTY_PATTERN = "//S.*";  

   

    // 日期格式  

    static final String DATE_PATTERN = "yyyy/MM/dd";  

   

    // 验证用户输入日期的正则表达式  

    static final String DATE_FORMAT_PATTERN = "^//d{4}///d{2}///d{2}$";  

   

    // 预定义的图书类型  

    static HashMap<String, String> TYPES = new LinkedHashMap<String, String>();  

   

    static {  

        TYPES.put("1", "科学类");  

        TYPES.put("2", "文学类");  // 新的类别可以继续在后面添加  

        TYPE_MENU = createTypeMenu();  

    }  

   

    // 生成选择类别的菜单  

    private static String createTypeMenu() {  

        String str = "";  

        for (String index : TYPES.keySet()) {  

            str += index + ". " + TYPES.get(index) + "/n";  

        }  

        return str + "请选择书的类型:";  

    }  

   

   

    private HashMap<Integer, Command> commands = new HashMap<Integer, Command>();  

   

    private ArrayList<Book> books = new ArrayList<Book>();  

   

    private ArrayList<Reader> readers = new ArrayList<Reader>();  

   

    // 程序入口。这里创建一个 LibrarySimulator 用于模拟界面。  

    public static void main(String[] args) {  

        new LibrarySimulator().start();  

    }  

   

    /** 

     * 构造函数 

     */  

    public LibrarySimulator() {  

        commands.put(1, new Command1());  

        commands.put(2, new Command2());  

        commands.put(3, new Command3());  

        commands.put(4, new Command4());  

        commands.put(5, new Command5());  

        commands.put(6, new Command6());  

        commands.put(7, new Command7());  

        commands.put(8, new Command8());  

    }  

   

    /** 

     * 这里接受用户输入,执行操作,然后再等待用户输入,这样不停的循环。 

     */  

    private void start() {  

        String index = prompt(MAIN_MENU, DIGIT_CHOICE_PATTERN);  

   

        while (!index.equals("9")) {  

            executeCommand(index);  

            index = prompt(MAIN_MENU, DIGIT_CHOICE_PATTERN);  

        }  

    }  

   

    // 根据序号执行命令  

    private void executeCommand(String index) {  

        Command command = commands.get(Integer.parseInt(index));  

        if (command != null) {  

            String result = command.execute();  

            System.out.println(result + "/n");  

        }  

    }  

   

    // 打印一条提示信息,然后读取并返回用户输入  

    private String prompt(String message, String pattern) {  

        System.out.print(message);  

        if (pattern == null) {  

            return readInput();  

        } else {  

            String result = "";  

            while (!result.matches(pattern)) {  

                result = readInput();  

            }  

            return result;  

        }  

    }  

   

    // 读取用户输入  

    private String readInput() {  

        try {  

            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));  

            return reader.readLine();  

        } catch (IOException e) {  

            e.printStackTrace();  

            return "";  

        }  

    }  

   

    // 根据名字查找读者。找不到则返回 null。  

    private Reader getReaderByName(String readerName) {  

        for (Reader reader : readers) {  

            if (reader.getName().equals(readerName)) {  

                return reader;  

            }  

        }  

        return null;  

    }  

   

    // 根据名字查找图书。找不到则返回 null。  

    private Book getBookByName(String bookName) {  

        for (Book book : books) {  

            if (book.getName().equals(bookName)) {  

                return book;  

            }  

        }  

        return null;  

    }  

   

    /*===================================================================*/  

   

    /** 

     * 代表命令的抽象类 

     */  

    private abstract class Command {  

   

        protected abstract String execute();  

    }  

   

    /////////////////////////////////////////////////// 列出所有图书  

    private class Command1 extends Command {  

   

        protected String execute() {  

            for (Book book : getBooks()) {  

                System.out.println(book);   // 这里会自动调用 book.toString()  

            }  

            return "命令完成。";  

        }  

   

        private ArrayList<Book> getBooks() {  

            ArrayList<Book> result = new ArrayList<Book>();  

   

            for (Book book : books) {  

                if (isValid(book)) {  

                    result.add(book);  

                }  

            }  

            return result;  

        }  

   

        // 考虑到第 1、2、3 条命令大体相同,这里提供了一个给子类覆写的方法  

        protected boolean isValid(Book book) {  

            return true;  

        }  

    }  

   

    ///////////////////////////////////////////////////// 列出已借出的书。  

    // 注意它的父类不是 Command,而是 Command1。这样节省了很多重复代码  

    private class Command2 extends Command1 {  

   

        @Override  

        protected boolean isValid(Book book) {  

            return book.isBorrowed();  

        }  

    }  

   

    //////////////////////////////////////////////////////// 列出过期未还的书  

    private class Command3 extends Command1 {  

   

        @Override  

        protected boolean isValid(Book book) {  

            // 判断一本书接触过期与否的方法最好在 Book 类中去实现。  

            return book.isExpired();  

        }  

    }  

   

    /////////////////////////////////////////////// 创建图书  

    private class Command5 extends Command {  

   

        protected String execute() {  

            String type = getType();  

            String name = getName();  

            if (getBookByName(name) == null) {  

                books.add(new Book(type, name));  

                return "图书添加成功。";  

            } else {  

                return "图书添加失败:名称已存在。";  

            }  

        }  

   

        // 获得用户输入的书名  

        private String getName() {  

            return prompt("请输入书名:", NOT_EMPTY_PATTERN);  

        }  

   

        // 获得用户选择的图书类型  

        private String getType() {  

            return prompt(TYPE_MENU, DIGIT_CHOICE_PATTERN);  

        }  

    }  

   

    /////////////////////////////////////////////////////// 列出所有读者  

    private class Command4 extends Command {  

   

        protected String execute() {  

            for (Reader reader : readers) {  

                System.out.println(reader);  

            }  

            return "命令完成。";  

        }  

    }  

   

    /////////////////////////////////////////////////////// 创建读者  

    private class Command6 extends Command {  

   

        protected String execute() {  

            String name = getName();  

            if (getReaderByName(name) == null) {  

                readers.add(new Reader(name));  

                return "读者创建成功。";  

            } else {  

                return "读者创建失败:名字已经存在。";  

            }  

        }  

   

        public String getName() {  

            return prompt("请输入读者名字:", NOT_EMPTY_PATTERN);  

        }  

    }  

   

    /////////////////////////////////////////////////////// 借书  

    private class Command7 extends Command {  

   

        protected String execute() {  

            Reader reader = getReader();  

            if (reader == null) {  

                System.out.println("命令取消。");  

                return "";  

            }  

   

            Book book = getBook();  

            if (book == null) {  

                System.out.println("命令取消。");  

                return "";  

            }  

   

            String borrowDate = getBorrowDate();  

   

            book.borrowBy(reader.getName(), borrowDate);  

            reader.addBorrowCount();  

   

            return "成功借出。";  

        }  

   

        private String getBorrowDate() {  

            String now = new SimpleDateFormat(LibrarySimulator.DATE_PATTERN).format(new Date());  

            String date = null;  

            while (date == null || !date.matches(DATE_FORMAT_PATTERN)) {  

                date = prompt("请输入结束日期(如" + now + ")", NOT_EMPTY_PATTERN);  

            }  

            return date;  

        }  

   

        private Book getBook() {  

            Book book = null;  

            while (book == null || book.isBorrowed()) {  

                String bookName = prompt("请输入图书名字:", null);  

                if (bookName.equals("")) {  

                    return null;  

                }  

   

                book = getBookByName(bookName);  

                if (book == null) {  

                    System.out.println("图书不存在。");  

                } else if (book.isBorrowed()) {  

                    System.out.println("图书已经被借出。");  

                }  

            }  

            return book;  

        }  

   

        private Reader getReader() {  

            Reader reader = null;  

            while (reader == null || !reader.canBorrow()) {  

                String readerName = prompt("请输入读者名字:", null);  

                if (readerName.equals("")) {  

                    return null;  

                }  

   

                reader = getReaderByName(readerName);  

                if (reader == null) {  

                    System.out.println("读者不存在。");  

                } else if (!reader.canBorrow()) {  

                    System.out.println("该读者已经借了" + Reader.MAX_BORROW + " 本书,不能继续借了。");  

                }  

            }  

            return reader;  

        }  

    }  

   

    ///////////////////////////////////////////// 还书  

    private class Command8 extends Command {  

   

        protected String execute() {  

            Reader reader = getReader();  

            if (reader == null) {  

                System.out.println("命令取消。");  

                return "";  

            }  

   

            Book book = getBook(reader);  

            if (book == null) {  

                System.out.println("命令取消。");  

                return "";  

            }  

   

            reader.reduceBorrowCount();  

            book.returned();  

            return "操作成功。";  

        }  

   

        private Book getBook(Reader reader) {  

            Book book = null;  

            while (book == null || !reader.getName().equals(book.getBorrower())) {  

                String bookName = prompt("请输入图书名字:", null);  

                if (bookName.equals("")) {  

                    return null;  

                }  

   

                book = getBookByName(bookName);  

                if (book == null) {  

                    System.out.println("图书不存在。");  

                } else if (!reader.getName().equals(book.getBorrower())) {  

                    System.out.println("该读者没有借出这本书。");  

                }  

            }  

            return book;  

        }  

   

        private Reader getReader() {  

            Reader reader = null;  

            while (reader == null) {  

                String readerName = prompt("请输入读者名字:", null);  

                if (readerName.equals("")) {  

                    return null;  

                }  

   

                reader = getReaderByName(readerName);  

                if (reader == null) {  

                    System.out.println("读者不存在。");  

                }  

            }  

            return reader;  

        }  

    }  

}  

   

// 图书  

class Book {  

   

    public static final int EXPIRE_DAYS = 21;   // 可借出天数,超过就算过期  

   

    private String type;  

   

    private String name;  

   

    private String borrowedBy = null;  

   

    private String borrowDate = null;  

   

    Book(String type, String name) {  

        this.type = type;  

        this.name = name;  

    }  

   

    @Override  

    public String toString() {  

        String str = String.format("类别:%s  书名:%s", LibrarySimulator.TYPES.get(type), name);  

        if (isBorrowed()) {  

            str += "  借出人:" + borrowedBy + "  借出时间:" + borrowDate;  

        }  

        return str;  

    }  

   

    public boolean isBorrowed() {  

        return borrowedBy != null;  

    }  

   

    public String getName() {  

        return name;  

    }  

   

    public String getBorrowDate() {  

        return borrowDate;  

    }  

   

    /** 

     * 图书借出 

     * 

     * @param name 读者名字 

     * @param date 借出日期。格式:参见 {@link LibrarySimulator#DATE_PATTERN} 

     */  

    public void borrowBy(String name, String date) {  

        this.borrowedBy = name;  

        this.borrowDate = date;  

    }  

   

    public boolean isExpired() {  

        if (borrowDate == null) {  

            return false;   // 没有借出的书不出现在过期未还列表当中,所以这里返回 false。  

        }  

   

        // 从当前时间往前推 3 个星期,如果还在借书日期之后,说明借书已经超过 3 个星期了  

        String threeWksAgo = get3WeeksAgo();  

        return threeWksAgo.compareTo(borrowDate) > 0;  

    }  

   

    // 获得 3 个星期前的日期  

    private String get3WeeksAgo() {  

        SimpleDateFormat f = new SimpleDateFormat(LibrarySimulator.DATE_PATTERN);  

        Calendar c = Calendar.getInstance();  

        c.add(Calendar.DAY_OF_MONTH, -EXPIRE_DAYS);  

        return f.format(c.getTime());  

    }  

   

    public void returned() {  

        this.borrowBy(null, null);  

    }  

   

    public String getBorrower() {  

        return borrowedBy;  

    }  

}  

   

// 读者  

class Reader {  

   

    // 每位读者最多可同时借出 3 本书  

    public static final int MAX_BORROW = 3;  

   

    private String name;  

   

    private int borowCount = 0;  

   

    public int getBorowCount() {  

        return borowCount;  

    }  

   

    Reader(String name) {  

        this.name = name;  

    }  

   

    public String getName() {  

        return name;  

    }  

   

    public void addBorrowCount() {  

        borowCount++;  

    }  

   

    public void reduceBorrowCount() {  

        borowCount--;  

    }  

   

    public boolean canBorrow() {  

        return borowCount < MAX_BORROW;  

    }  

   

    @Override  

    public String toString() {  

        return name;  

    }  

}  

原创粉丝点击