图书管理系统(框架实现)

图书管理系统(框架实现)

要构建这样的一个系统,最难的其实就是找对象。让我们思考一下,在这样一个系统下,有哪些对象呢?最容易想到的,应该就是书和人。我们先从书开始考虑。

1、package 1:book

  • class:Book ,我们可以创建一个Book类来实例化书本的对象,那么在Book类中应该设置书的哪些属性呢?根据简介,我们设置了name,author,price,type和isborrowed五个属性。为了体现封装性,我们都用private修饰它们。为了在类外部调用它们,我们又都为前四个成员变量设置了Getter and Setter方法(先不考虑isborrowed)。为了便于初始化,我们自己写一个包含前四个变量作为参数的构造方法。如下所示:
public class Book {
    private String name;
    private String author;
    private int price;
    private String type;
    private boolean isBorrowed;

    public Book(String name, String author, int price, String type) {
        this.name = name;
        this.author = author;
        this.price = price;
        this.type = type;
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public boolean isBorrowed() {
        return isBorrowed;
    }

为了打印出的格式与简介中所示一致,我们可以在Book类中重写toString方法:

 public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", price=" + price +
                ", type='" + type + '\'' +
                ( (isBorrowed == true) ? ",已借出" : ",未借出" )+
                //", isBorrowed=" + isBorrowed +
                '}';
    }

原理:println打印时调用的是Object类中的toString方法,而所有类都默认继承了Object类,重写toString方法后,调用时发生动态绑定,调用子类重写的方法,导致打印格式改变。

  • class :BookList,有了书本之后,我们还需要一个地方(数组)来存放、操作这些书,于是我们构建了BookList类,在其中定义一个数组Book[ ],同时创建变量usedSize来表示有多少位置被使用了。同样,我们使用private修饰,并提供Getter and Setter方法。我们还可以在BookList类中写一个构造方法创建数组对象,规定最大存放书本量与已使用书本量。如下:
 public BookList() {
        this.books = new Book[10];
        this.usedSize = 0;
    }

    public int getUsedSize() {
        return usedSize;
    }

    public void setUsedSize(int usedSize) {
        this.usedSize = usedSize;
    }

接下来,我们就迎来了第一个难题:如何组织这些操作,让每一个操作都独立。

package 2 :operation

方法一:我们把每一个操作都写成一个类,需要时直接调用即可。
但是这种写法比较复杂,输入的不同需要使用多分支结构判断实现调用。
方法二:我们还可以定义一个接口IOPeration里面放入一个work方法(传入BookList),以便后面创建一个接口数组,在其中对应位置实例化对应的对象,实现类型的统一。
如下:

public interface IOPeration {
    void work(BookList booklist);
}

package 3 :user

  • class :User,我们也给用户创建一个类,在其中设置成员变量name,可以使用protected修饰。我们要实现面对管理员和普通用户打印不同的菜单。我们可以考虑触发动态绑定,实现多态。根据多态发生的条件,我们要:
    1、创建AdminUser和NormalUser两个类来继承User类。
    2、这两个子类重写User类中的menu方法。
    由此,User类中的menu方法不必具体实现,可以设置为抽象类,增加安全性。
    我们还需要定义一个ioPerations数组,实现对应下标(类)元素的实例化,调用其中的work方法,实现对应操作。
public  abstract class User {
    protected String name;
    protected IOPeration[] ioPerations;

    public User(String name) {
        this.name = name;
    }
    public abstract int menu();
    public void doOperation(int choice, BookList bookList) {
        IOPeration ioPeration = this.ioPerations[choice];
        ioPeration.work(bookList);
    }
}

  • class :AdminUser ,写一个构造方法来初始化接口数组,并重写menu方法。
public class AdminUser extends User {
    public AdminUser(String name) {
        super(name);
        this.ioPerations = new IOPeration[]{
                new ExitOperation(),
                new FindOperation(),
                new AddOperation(),
                new DelOperation(),
                new ShowOperation()
        };
    }

    public int menu() {
        System.out.println("********管理员菜单********");
        System.out.println("1.查找图书");
        System.out.println("2.新增图书");
        System.out.println("3.删除图书");
        System.out.println("4.显示图书");
        System.out.println("0.退出系统");
        System.out.println("************************");
        System.out.println("请输入你的操作:");
        Scanner scanner = new Scanner(System.in);
        int choice = scanner.nextInt();
        return choice;
    }
}
  • class :NormalUser ,同上。
public class NormalUser extends User{
    public NormalUser(String name) {
        super(name);
        this.ioPerations = new IOPeration[]{
                new ExitOperation(),
                new FindOperation(),
                new BorrowOperation(),
                new ReturnOperation()
        };
    }

    public int menu() {
        System.out.println("********普通用户菜单********");
        System.out.println("1.查找图书");
        System.out.println("2.借阅图书");
        System.out.println("3.归还图书");
        System.out.println("0.退出系统");
        System.out.println("***************************");
        System.out.println("请输入你的操作:");
        Scanner scanner = new Scanner(System.in);
        int choice = scanner.nextInt();
        return choice;
    }
}

main方法

我们要创建一个login方法来登录,choice变量接收后,进行判断,根据值的不同返回AdminUser或NormalUser对象。

public class Main {
    public static User login() {
        System.out.println("请输入你的姓名:");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        System.out.println("请输入你的身份,1:管理员  2:普通用户-》");
        int choice = scanner.nextInt();
        if(choice == 1) {
            return new AdminUser(name);
        }else {
            return new NormalUser(name);
        }
    }

    public static void main(String[] args) {

        BookList bookList = new BookList();
        //此时这个user到底指向的是 管理员对象 还是 普通用户对象 不知道的
        // user =  new AdminUser(name);
        // user =  new NormalUser(name);
        User user = login();
        while (true) {//循环打印菜单
            int choice = user.menu();
            //根据你菜单返回的choice来执行对应的操作
            user.doOperation(choice, bookList);
        }
    }
}

你可能感兴趣的:(java)