Java设计模式之外观模式示例详解
261
2022-08-02
目录1.book包2.user包3.operate包
java中的最主要的语法之前基本都介绍完毕,本篇将使用之前的内容来写一个简单的图书管理系统,中间会展示部分代码来讲解,源码地址在这项目: 个人练习的项目 - Gitee.com
首先还是来看看运行的效果
我们来分析一下:
Java中是通过对象之间的交互来解决事情的,所以我们来看看有哪些对象
首先显而易见的两个对象:用户和书,所以创建两个包book和user
通过上图可以看到:不同用户之间有相同的操作,也有不同的操作,所以不妨将所有的操作都放在一个包中,需要什么操作直接调用即可,我将这个包命名为operate
1.book包
package book;
public class Book {
private String name;
private String author;
private String type;
private int price;
private boolean borrow;
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;
}
}
既然有书,那么就需要书架来存放书,所以在book包中再定义一个类为BookShelf用来存放书以及记录书的数量,存放书可以用Book类数组实现
public class BookShelf {
private Book[] books=new Book[1000];
private int count; //记录书的数量
}
由于数组不能直接访问,所以在类中增加一个获取数组下标的方法,而访问数组的方法一般都是对书进行操作,所以setBook方法也进行修改
package book;
public class BookShelf {
private Book[] books=new Book[1000];
private int count; //记录书的数量
public void setBooks(int pos,Book book) {
books[pos] = book;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public BookShelf() {
books[0]=new Book("呐喊","鲁迅","小说集",30); //默认初始有一本书,写不写随你
this.count=1;
}
//获取下标对应的书
public Book pos(int i) {
return books[i];
}
}
book包初步的代码就到这,继续下一个包
2.user包
包中肯定会有普通用户(NormalUser)和管理员(AdminUser)两个类,但重点是如何实现图中的不同用户有不同的操作
那我们先将登陆方法写出来,然后分析:
public static void login() {
System.out.println("输入姓名:");
Scanner scanner=new Scanner(System.in);
String name=scanner.nextLine();
System.out.println("输入你身份:1.管理员 2.普通用户");
int i=scanner.nextInt();
if(i==1) {
//管理员
} else {
//普通用户
}
}
方法根据不同的数字来判断是哪种用户,所以返回值应该是返回一个类,但这里有两个类,为解决这个问题,我们可以让NormalUser和AdminUser都继承同一个父类,方法只要返回父类即可
父类代码如下:
public abstract class User {
private String name;
public User(String name) {
this.name = name;
}
public abstract void menu(); //菜单抽象方法,子类实现
}
子类代码:
public class AdminUser extends User{
public AdminUser(String name) {
super(name);
}
@Override
public void 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("选择操作");
}
}
public class NormalUser extends User{
public NormalUser(String name) {
super(name);
}
@Override
public void menu() {
System.out.println("欢迎使用");
System.out.println("1.查找图书");
System.out.println("2.借阅图书");
System.out.println("3.归还图书");
System.out.println("0.退出系统");
System.out.println("选择操作");
}
}
不同用户对应着不同的操作,但有相同的操作数,所以两个类需要有一个数组来存放各自的方法来防止出错,而且这个数组是要在用户选择之前就准备好,所以数组应该是在构造方法内,修改后的类如下:
public abstract class User {
private String name;
public IOperate[] ioperate;
public void chooseOperate(int choice,BookShelf bookShelf) {
ioperate[choice].work(bookShelf);
}
public User(String name) {
this.name = name;
}
public abstract int menu();
}
public class AdminUser extends User{
public AdminUser(String name) {
super(name);
this.ioperate=new IOperate[] {
new Exit(),
new FindBook(),
new AddBook(),
new DelBook(),
new DisplayBook(),
};
}
@Override
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("选择操作");
Scanner scanner=new Scanner(System.in);
int choice=scanner.nextInt();
return choice;
}
}
public class NormalUser extends User{
public NormalUser(String name) {
super(name);
this.ioperate=new IOperate[] {
new Exit(),
new FindBook(),
new BorrowBook(),
new ReturnBook(),
};
}
@Override
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("选择操作");
Scanner scanner=new Scanner(System.in);
int choice=scanner.nextInt();
return choice;
}
}
3.operate包
图书的增删改查等操作其实都是在对Book数组来进行操作的,所以这些方法的参数都是BookShelf类,那么我们可以定义一个接口,接口内定义此方法,然后其它类实现此接口即可
接口代码:
package operate;
import book.BookShelf;
public interface IOperate {
public void work (BookShelf bookShelf);
}
至于对书的操作,这里以增加书籍为例
我们需要知道书的信息,然后要有一个Book类来接收,最后放到数组中
按照这个逻辑,之前的Book类就需要修改:在Book类中添加一个构造方法以便接收书的信息,注意方法在数组中的位置要和你自己写的菜单中的位置对应
public Book(String name, String author, String type, int price) {
this.name = name;
this.author = author;
this.type = type;
this.price = price;
}
增加书的方法代码:
public class AddBook implements IOperate {
@Override
public void work(BookShelf bookShelf) {
System.out.pekMZcmhcgrintln("请输入图书的名字:");
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine();
String author = scanner.nextLine();
System.out.println("请输入图书的类型:");
String type = scanner.nextLine();
System.out.println("请输入图书的价格:");
int price = scanner.nextInt();
Book book = new Book(name,author,type,price);
int count=bookShelf.getCount();
bookShelf.setBooks(count,book);
bookShelf.setCount(count+1);
System.out.println("新增成功");
}
}
注:
1.由于引用变量默认是输出修改的地址,所以要打印书的内容的话需要在类Book中重写toString方法
2.退出方法在退出前需遍历数组将其指向的对象都改为null方便回收,虽然程序结束后系统也会回收,但你要知道大型工程里面有些程序一旦跑起来后想要停下来不是那么容易的
到这里这个图书管理系统基本完成,完
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~