前言
原文鏈接: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("++++++++++++++++++++++++++++");
}
}