前言
原文链接:https://blog.csdn.net/FBB360JAVA/article/details/79256570
本文重在code review。
实现的只是一个简易的管理系统,控制台输入、输入。以及增删改查等操作。
项目结构
其中 RunTest 是用来测试ZooManager的。
核心功能实现是在 ZooManager 中。
java 代码
AbstractAnimal
package zoo.entity.base;
import java.io.*;
import java.util.Objects;
/**
* 动物类
* 注意:当动物名和动物类型一致时,认为是同一个动物
* @author Feng
*/
public abstract class AbstractAnimal implements Serializable {
private static final long serialVersionUID = 799133399232518077L;
/**动物的名字*/
private String name;
/**动物的类型*/
private String type;
public AbstractAnimal() {
}
public AbstractAnimal(String name) {
type = getType();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
* 获得动物的类类型
* @return 返回当前对象的类的简单名字(转小写)
*/
public String getType() {
return this.getClass().getSimpleName().toLowerCase();
}
public void setType(String type){
this.type = type;
}
/**
* 深克隆:需要序列化。
* 为后期扩展而写(可能会用到,目前程序中没有使用)
*/
@Deprecated
public AbstractAnimal deepClone() throws IOException, ClassNotFoundException {
// 将对象写入流中
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
// 将对象从流中取出
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
return (AbstractAnimal)(ois.readObject());
}
@Override
public String toString() {
return String.join("\t\t", name, type);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
AbstractAnimal that = (AbstractAnimal) o;
return Objects.equals(name, that.name) &&
Objects.equals(type, that.type);
}
@Override
public int hashCode() {
return Objects.hash(name, type);
}
}
Cat
package zoo.entity;
import zoo.entity.base.AbstractAnimal;
import zoo.inter.Leg;
/**
* 猫
* @author Feng
*/
public class Cat extends AbstractAnimal implements Leg {
private static final long serialVersionUID = -2919986919068143322L;
public Cat() {
}
public Cat(String name) {
super(name);
}
@Override
public int getLegNum() {
return 4;
}
}
Dog
package zoo.entity;
import zoo.entity.base.AbstractAnimal;
import zoo.inter.Leg;
/**
* 狗
* @author Feng
*/
public class Dog extends AbstractAnimal implements Leg {
private static final long serialVersionUID = -8956792508217398988L;
public Dog() {
}
public Dog(String name) {
super(name);
}
@Override
public int getLegNum() {
return 4;
}
}
Leg
package zoo.inter;
/**
* 腿
* @author Feng
*/
public interface Leg {
/**
* 获得腿的条数
* @return 腿的数目
*/
int getLegNum();
default void run(){
System.out.println("我用"+ getLegNum() + "条腿跑!");
}
}
Swim
package zoo.inter;
/**
* 游泳
* @author Feng
*/
public interface Swim {
}
ZooManager
package zoo.manager;
import zoo.entity.base.AbstractAnimal;
import java.util.Collections;
import java.util.List;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toList;
/**
* 动物园管理者:
* 设计为单例,提供常用的方法来操作动物的信息
*/
public class ZooManager {
private static ZooManager zooManager = null;
private final List<AbstractAnimal> animalList;
private ZooManager(List<AbstractAnimal> animalList) {
this.animalList = animalList;
}
/**
* 得到动物园管理者对象
* @param animalList 动物列表
*/
public static ZooManager manager(List<AbstractAnimal> animalList){
if(zooManager == null){
zooManager = new ZooManager(animalList);
}
return zooManager;
}
/**
* 得到动物园管理者对象(动物列表为空)
* @return 管理者对象
*/
public static ZooManager manager(){
return manager(Collections.emptyList());
}
/**
* 获取所有动物信息
* @return 所有动物列表
*/
public List<AbstractAnimal> getAnimalList(){
return animalList;
}
/**
* 通过 Class 来获取指定的类型的动物列表
* @param abstractAnimalClass examples: Cat.class
* @return 动物列表
*/
public List<AbstractAnimal> getAnimalListByClass(Class<?> abstractAnimalClass){
return animalList.stream()
.filter(abstractAnimal -> abstractAnimal.getClass() == abstractAnimalClass)
.collect(toList());
}
/**
* 通过 type 字符串来获取指定类型的动物列表
* @param type examples: "cat"
* @return 动物列表
*/
public List<AbstractAnimal> getAnimalListByType(String type){
return animalList.stream()
.collect(groupingBy(AbstractAnimal::getType, toList()))
.getOrDefault(type, Collections.emptyList());
}
/**
* 通过动物的名字获取动物列表(名字可能重复,因此结果是个列表)
* @param name 动物的名字
* @return 名字是 name 的所有的动物
*/
public List<AbstractAnimal> getAnimalListByName(String name){
return animalList.stream()
.collect(groupingBy(AbstractAnimal::getName, toList()))
.getOrDefault(name, Collections.emptyList());
}
/**
* 增加一个动物
* @param animal 任意一个动物
*/
public boolean addAnimal(AbstractAnimal animal){
return animalList.add(animal);
}
/**
* 删除动物
* @param animal 动物对象
*/
public boolean deleteAnimal(AbstractAnimal animal){
return animalList.remove(animal);
}
/**
* 修改动物信息(其实是一种暴力的方式,删除了原先的旧的信息,将新的添加进去)
* @param from 目标动物信息
* @param to 新的动物信息
* @return 修改成功返回 true
*/
public boolean updateAnimal(AbstractAnimal from, AbstractAnimal to){
if(containsAnimal(from)){
deleteAnimal(from);
}
return addAnimal(to);
}
public boolean containsAnimal(AbstractAnimal animal){
return animalList.contains(animal);
}
}
RunTest
package zoo.client;
import zoo.entity.Cat;
import zoo.entity.Dog;
import zoo.entity.base.AbstractAnimal;
import zoo.manager.ZooManager;
import java.util.ArrayList;
import java.util.List;
/**
* 运行:测试
*/
public class RunTest {
public static void main(String[] args) {
// 初始化数据
final List<AbstractAnimal> animalList = new ArrayList<AbstractAnimal>(){
private static final long serialVersionUID = -2569394013903999819L;
{
add(new Cat("Tom"));
add(new Cat("Divid"));
add(new Cat("Switch"));
add(new Cat("小冯"));
add(new Dog("愣娃"));
add(new Dog("小冯"));
}
};
// 获得管理者
ZooManager manager = ZooManager.manager(animalList);
// 打印所有动物信息
manager.getAnimalList().forEach(System.out::println);
// 通过类得到指定类型的动物列表
manager.getAnimalListByClass(Dog.class).forEach(System.out::println);
// 通过名字获取动物(可能重复)
manager.getAnimalListByName("小冯").forEach(System.out::println);
// 通过类型获得动物列表
manager.getAnimalListByType("cat").forEach(System.out::println);
// 增加一个动物
Cat cat = new Cat("小刘");
manager.addAnimal(cat);
// true
System.out.println(manager.containsAnimal(cat));
// 修改动物信息
manager.updateAnimal(cat, new Cat("小小刘"));
// 删除:true
System.out.println(manager.deleteAnimal(new Cat("小小刘")));
}
}
Client
package zoo.client;
import zoo.entity.Cat;
import zoo.entity.Dog;
import zoo.entity.base.AbstractAnimal;
import zoo.manager.ZooManager;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
/**
* 客户端
* @author Feng
*/
public class Client {
private static BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
/** 初始化数据*/
private static final List<AbstractAnimal> ANIMAL_LIST = new ArrayList<AbstractAnimal>(){
private static final long serialVersionUID = -2569394013903999819L;
{
add(new Cat("Tom"));
add(new Cat("Divid"));
add(new Cat("Switch"));
add(new Cat("小冯"));
add(new Dog("愣娃"));
add(new Dog("小冯"));
}
};
/** 创建管理者*/
private final static ZooManager MANAGER = ZooManager.manager(ANIMAL_LIST);
/** 初始化执行策略*/
private final static Map<Integer, Consumer<String>> MAP = new HashMap<Integer, Consumer<String>>(16){
private static final long serialVersionUID = 8594371374378459978L;
{
put(0, (title) -> {
System.out.println(title);
MANAGER.getAnimalList().forEach(System.out::println);
});
put(1, (title) -> {
String type = in("请输入你要查找的动物的类型(dog,cat):");
System.out.println(title);
MANAGER.getAnimalListByType(type).forEach(System.out::println);
});
put(2, (title) -> {
String name = in("请输入你要查找的动物的名字:");
System.out.println(title);
MANAGER.getAnimalListByName(name).forEach(System.out::println);
});
put(3, (title) -> {
String name = in("请输入你要增加的动物的名字:");
String type = in("请是输入你要增加的动物的类型:");
AbstractAnimal animal = null;
try {
animal = (AbstractAnimal)Class.forName("zoo.entity." + type.substring(0,1).toUpperCase() + type.substring(1)).newInstance();
} catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
e.printStackTrace();
}
if(animal != null){
animal.setName(name);
animal.setType(type);
if(MANAGER.containsAnimal(animal)){
System.out.println("该动物已经存在了,不能重复添加。");
} else {
MANAGER.addAnimal(animal);
System.out.println(name + "已经添加成功!");
}
} else {
System.out.println("程序内部错误,可能是你输入的动物类型不存在导致的。");
}
});
put(4, (title) -> {
String name = in("请输入你要修改的动物的名字:");
String type = in("请是输入你要修改的动物的类型:");
String newName = in("请输入你要设置的新的动物的名字:");
String newType = in("请是输入你要设置的新的动物的类型:");
try {
AbstractAnimal from = (AbstractAnimal)Class.forName("zoo.entity." + type.substring(0,1).toUpperCase() + type.substring(1)).newInstance();
from.setName(name);
from.setType(type);
AbstractAnimal to = (AbstractAnimal)Class.forName("zoo.entity." + newType.substring(0,1).toUpperCase() + newType.substring(1)).newInstance();
to.setName(newName);
to.setType(newType);
if(MANAGER.updateAnimal(from, to)){
System.out.println("已经修改成功了!");
} else {
System.out.println("请检查你的输入名或类型。");
}
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
e.printStackTrace();
}
});
put(5, (title) -> {
String name = in("请输入你要删除的动物的名字:");
String type = in("请是输入你要删除的动物的类型:");
try {
AbstractAnimal animal = (AbstractAnimal) Class.forName("zoo.entity." + type.substring(0, 1).toUpperCase() + type.substring(1)).newInstance();
animal.setName(name);
animal.setType(type);
if(MANAGER.deleteAnimal(animal)){
System.out.println(name + "已经被删除了!");
} else {
System.out.println("不存在该动物!请检查你的输入。");
}
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
e.printStackTrace();
}
});
}
};
public static void main(String[] args) {
Client client = new Client();
boolean isContinue = true;
while (isContinue){
String choose = client.runClient();
switch (choose){
case "0":
client.setStat(0);
break;
case "1":
client.setStat(1);
break;
case "2":
client.setStat(2);
break;
case "3":
client.setStat(3);
break;
case "4":
client.setStat(4);
break;
case "5":
client.setStat(5);
break;
default:
isContinue = false;
break;
}
System.out.println("++++++++++++++++++++++++++++");
}
}
private String runClient(){
System.out.println("+++++++++++++zoo++++++++++++");
System.out.println("\t0. 查看所有动物信息");
System.out.println("\t1. 按动物类型查看");
System.out.println("\t2. 按动物名查看");
System.out.println("\t3. 增加一个动物");
System.out.println("\t4. 修改一个动物");
System.out.println("\t5. 删除一个动物");
System.out.println("\t 输入其他任意键退出!");
return in("请输入你的选择:");
}
/**
* 控制台打印tips,然后接收从键盘输入的字符串
* @param tips 提示信息
* @return 键盘接收的字符串
*/
private static String in(String tips){
System.out.println(tips);
String result = null;
try {
result = bufferedReader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
/**
* 状态设计模式
* @param stat 状态
*/
private void setStat(int stat) {
MAP.get(stat).accept("动物名\t\t动物类型");
}
}
程序运行
正常运行使用 Client 类。
测试使用 RunTest。
结果展示
+++++++++++++zoo++++++++++++
0. 查看所有动物信息
1. 按动物类型查看
2. 按动物名查看
3. 增加一个动物
4. 修改一个动物
5. 删除一个动物
输入其他任意键退出!
请输入你的选择:
3
请输入你要增加的动物的名字:
小晴
请是输入你要增加的动物的类型:
cat
小晴已经添加成功!
++++++++++++++++++++++++++++
+++++++++++++zoo++++++++++++
0. 查看所有动物信息
1. 按动物类型查看
2. 按动物名查看
3. 增加一个动物
4. 修改一个动物
5. 删除一个动物
输入其他任意键退出!
请输入你的选择:
2
请输入你要查找的动物的名字:
小晴
动物名 动物类型
小晴 cat
++++++++++++++++++++++++++++
+++++++++++++zoo++++++++++++
0. 查看所有动物信息
1. 按动物类型查看
2. 按动物名查看
3. 增加一个动物
4. 修改一个动物
5. 删除一个动物
输入其他任意键退出!
请输入你的选择:
4
请输入你要修改的动物的名字:
小晴
请是输入你要修改的动物的类型:
cat
请输入你要设置的新的动物的名字:
小小晴
请是输入你要设置的新的动物的类型:
cat
已经修改成功了!
++++++++++++++++++++++++++++
+++++++++++++zoo++++++++++++
0. 查看所有动物信息
1. 按动物类型查看
2. 按动物名查看
3. 增加一个动物
4. 修改一个动物
5. 删除一个动物
输入其他任意键退出!
请输入你的选择:
0
动物名 动物类型
Tom cat
Divid cat
Switch cat
小冯 cat
愣娃 dog
小冯 dog
小小晴 cat
++++++++++++++++++++++++++++
+++++++++++++zoo++++++++++++
0. 查看所有动物信息
1. 按动物类型查看
2. 按动物名查看
3. 增加一个动物
4. 修改一个动物
5. 删除一个动物
输入其他任意键退出!
请输入你的选择:
5
请输入你要删除的动物的名字:
小小晴
请是输入你要删除的动物的类型:
cat
小小晴已经被删除了!
++++++++++++++++++++++++++++
+++++++++++++zoo++++++++++++
0. 查看所有动物信息
1. 按动物类型查看
2. 按动物名查看
3. 增加一个动物
4. 修改一个动物
5. 删除一个动物
输入其他任意键退出!
请输入你的选择:
5
请输入你要删除的动物的名字:
小冯
请是输入你要删除的动物的类型:
cat
小冯已经被删除了!
++++++++++++++++++++++++++++
+++++++++++++zoo++++++++++++
0. 查看所有动物信息
1. 按动物类型查看
2. 按动物名查看
3. 增加一个动物
4. 修改一个动物
5. 删除一个动物
输入其他任意键退出!
请输入你的选择:
0
动物名 动物类型
Tom cat
Divid cat
Switch cat
愣娃 dog
小冯 dog
++++++++++++++++++++++++++++
+++++++++++++zoo++++++++++++
0. 查看所有动物信息
1. 按动物类型查看
2. 按动物名查看
3. 增加一个动物
4. 修改一个动物
5. 删除一个动物
输入其他任意键退出!
请输入你的选择:
最后
代码写完以后,我做的测试并不多,但基本功能都测试了。
还有就是各位大佬,求轻虐。
修改
Client 中的main方法
不使用 switch 语句了。
public static void main(String[] args) throws IOException {
Client client = new Client();
boolean isContinue = true;
while (isContinue){
String choose = client.runClient();
try {
// 此处也可使用正则匹配数字
int key = Integer.parseInt(choose);
if(MAP.containsKey(key)){
client.setStat(key);
} else {
System.err.println("不支持的操作!错误的输入:" + key);
}
}catch (Exception e){
System.err.println("无效的输入!程序需要退出吗?(y退出,其他任意键重新进入选择页面。)");
String str;
if((str = bufferedReader.readLine()) != null){
if("y".equalsIgnoreCase(str)){
isContinue = false;
}
}
}
System.out.println("++++++++++++++++++++++++++++");
}
}