- 前言
- 之前的文章
- 本次的源码
- AnimalTypeEnum
- SexEnum
- Animal
- AnimalFactory
- BaseAnimal
- Bird
- Cat
- Dog
- Fish
- AddAnimalFacade
- DeleteAnimalFacade
- Facade
- FacadeUtil
- ListFacade
- MainFacade
- SearchAnimalFacade
- UpdateAnimalFacade
- Manager
- ZooClient
- ZooManager
- PrintUtil
- 本次的运行效果
- 结论
鉴于各位小伙伴对这类入门级程序的热忱,本人对于之前的重构,再次重构。
本次设计,用到了简单工厂设计模式、门面设计模式,抽象类、接口、集合容器的增删改查、遍历集合等java知识点。
初版:
https://blog.csdn.net/FBB360JAVA/article/details/79256570
简易的动物园管理系统之Java8流式API的重构代码(使用 状态设计模式)
https://blog.csdn.net/FBB360JAVA/article/details/105627691
package org.feng.zoo.animals.enums;
public enum AnimalTypeEnum {
CAT("猫"),
DOG("狗"),
FISH("鱼"),
MONKEY("猴子"),
ELEPHANT("大象"),
BIRD("鸟");
private final String chineseDesc;
AnimalTypeEnum(String chineseDesc) {
this.chineseDesc = chineseDesc;
}
public String getChineseDesc() {
return chineseDesc;
}
public static void list() {
System.out.println("序号tt 动物类型");
String animalTypePattern = "%stt%s";
AnimalTypeEnum[] animalTypes = AnimalTypeEnum.values();
int length = AnimalTypeEnum.values().length;
for (int i = 0; i < length; i++) {
System.out.printf((animalTypePattern) + "%n", (i + 1), animalTypes[i].chineseDesc);
}
}
}
SexEnum
package org.feng.zoo.animals.enums;
public enum SexEnum {
MALE("雄性"), FEMALE("雌性");
private final String desc;
SexEnum(String desc) {
this.desc = desc;
}
public static void list() {
System.out.println("序号tt 动物性别");
String animalSexPattern = "%stt%s";
SexEnum[] animalTypes = SexEnum.values();
int length = SexEnum.values().length;
for (int i = 0; i < length; i++) {
System.out.printf((animalSexPattern) + "%n", (i + 1), animalTypes[i].desc);
}
}
public String getDesc() {
return desc;
}
}
Animal
package org.feng.zoo.animals;
import org.feng.zoo.animals.enums.AnimalTypeEnum;
import org.feng.zoo.animals.enums.SexEnum;
public interface Animal {
AnimalTypeEnum getType();
String getName();
SexEnum getSex();
void move();
}
AnimalFactory
package org.feng.zoo.animals;
import org.feng.zoo.animals.enums.AnimalTypeEnum;
import org.feng.zoo.animals.enums.SexEnum;
public class AnimalFactory {
public static BaseAnimal newAnimal(AnimalTypeEnum type, String name, SexEnum sexEnum) {
if (type == null) {
return null;
}
switch (type) {
case CAT:
return new Cat(name, sexEnum);
case DOG:
return new Dog(name, sexEnum);
case BIRD:
return new Bird(name, sexEnum);
case FISH:
return new Fish(name, sexEnum);
default:
return null;
}
}
}
BaseAnimal
package org.feng.zoo.animals;
import org.feng.zoo.animals.enums.AnimalTypeEnum;
import org.feng.zoo.animals.enums.SexEnum;
import java.util.Objects;
public abstract class BaseAnimal implements Animal {
protected String name;
protected SexEnum sex;
protected AnimalTypeEnum type;
protected BaseAnimal(String name) {
this.name = name;
}
public BaseAnimal(String name, SexEnum sex) {
this.name = name;
this.sex = sex;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
BaseAnimal that = (BaseAnimal) o;
// 当动物名字和动物类型相等时,表示是同一个动物
return Objects.equals(getType(), that.getType()) && Objects.equals(name, that.name);
}
@Override
public int hashCode() {
return Objects.hash(name + getType());
}
@Override
public String toString() {
String animalPattern = "%s tt %s";
return String.format(animalPattern, this.getType().getChineseDesc(), this.getName());
}
@Override
public SexEnum getSex() {
return sex;
}
public void setSex(SexEnum sex) {
if (sex == null) {
return;
}
this.sex = sex;
}
@Override
public String getName() {
return name;
}
public void setName(String name) {
if (name == null) {
return;
}
this.name = name;
}
public void setType(AnimalTypeEnum type) {
if (type == null) {
return;
}
this.type = type;
}
}
Bird
package org.feng.zoo.animals;
import org.feng.zoo.animals.enums.AnimalTypeEnum;
import org.feng.zoo.animals.enums.SexEnum;
public class Bird extends BaseAnimal {
public Bird(String name, SexEnum sex) {
super(name, sex);
this.type = AnimalTypeEnum.BIRD;
}
@Override
public AnimalTypeEnum getType() {
return this.type;
}
@Override
public void move() {
String movePattern = "%s[%s] 在天上飞";
System.out.printf((movePattern) + "%n", this.name, this.getType().getChineseDesc());
}
}
Cat
package org.feng.zoo.animals;
import org.feng.zoo.animals.enums.AnimalTypeEnum;
import org.feng.zoo.animals.enums.SexEnum;
public class Cat extends BaseAnimal {
public Cat(String name, SexEnum sex) {
super(name, sex);
this.type = AnimalTypeEnum.CAT;
}
@Override
public AnimalTypeEnum getType() {
return this.type;
}
@Override
public void move() {
String movePattern = "%s[%s] 在地上跑";
System.out.printf((movePattern) + "%n", this.name, this.getType().getChineseDesc());
}
}
Dog
package org.feng.zoo.animals;
import org.feng.zoo.animals.enums.AnimalTypeEnum;
import org.feng.zoo.animals.enums.SexEnum;
public class Dog extends BaseAnimal {
public Dog(String name, SexEnum sex) {
super(name, sex);
this.type = AnimalTypeEnum.DOG;
}
@Override
public AnimalTypeEnum getType() {
return this.type;
}
@Override
public void move() {
String movePattern = "%s[%s] 在地上跑";
System.out.printf((movePattern) + "%n", this.name, this.getType().getChineseDesc());
}
}
Fish
package org.feng.zoo.animals;
import org.feng.zoo.animals.enums.AnimalTypeEnum;
import org.feng.zoo.animals.enums.SexEnum;
public class Fish extends BaseAnimal {
public Fish(String name, SexEnum sex) {
super(name, sex);
this.type = AnimalTypeEnum.FISH;
}
@Override
public AnimalTypeEnum getType() {
return this.type;
}
@Override
public void move() {
String movePattern = "%s[%s] 在水里游";
System.out.printf((movePattern) + "%n", this.name, this.getType().getChineseDesc());
}
}
AddAnimalFacade
package org.feng.zoo.client.facade; import org.feng.zoo.animals.AnimalFactory; import org.feng.zoo.animals.BaseAnimal; import org.feng.zoo.animals.enums.AnimalTypeEnum; import org.feng.zoo.animals.enums.SexEnum; import org.feng.zoo.client.ZooManager; import org.feng.zoo.util.PrintUtil; import static org.feng.zoo.client.facade.Facade.sop; public class AddAnimalFacade implements FacadeDeleteAnimalFacade{ private void init() { sop("***************************动物园管理系统**************************"); sop("********************已选择 [3] 增加动物信息***********************"); } @Override public void render(ZooManager zooManager) { init(); sop("(Tips)可选择的动物类型如下:"); // 列出动物类型 zooManager.listAnimalTypes(); String animalTypeIndex = PrintUtil.in("请选择要增加的动物的类型序号"); AnimalTypeEnum animalType = zooManager.getAnimalTypeByIndex(PrintUtil.toIntIndex(animalTypeIndex)); // 动物名称 String animalName = PrintUtil.in("请输入要增加的动物名字"); sop("(Tips)可选择的动物性别如下:"); // 列出动物性别 zooManager.listAnimalSex(); String animalSexIndex = PrintUtil.in("请选择要增加的动物的性别序号"); SexEnum animalSex = zooManager.getAnimalSexByIndex(PrintUtil.toIntIndex(animalSexIndex)); BaseAnimal animal = AnimalFactory.newAnimal(animalType, animalName, animalSex); if (animal == null) { sop("不支持的动物类型"); return; } zooManager.add(animal); animal.move(); sop("增加动物成功!"); } }
package org.feng.zoo.client.facade; import org.feng.zoo.client.ZooManager; import org.feng.zoo.util.PrintUtil; import static org.feng.zoo.client.facade.Facade.sop; public class DeleteAnimalFacade implements FacadeFacade{ private void init() { sop("***************************动物园管理系统**************************"); sop("********************已选择 [5] 删除动物信息***********************"); } @Override public void render(ZooManager zooManager) { init(); sop("可供删除的动物列表如下:"); zooManager.listAnimals(); String needUpdateIndex = PrintUtil.in("请选择对应序号:"); boolean deleteSuccess = zooManager.delete(PrintUtil.toIntIndex(needUpdateIndex)); if (deleteSuccess) { sop("删除成功!"); } else { sop("删除失败!"); } } }
package org.feng.zoo.client.facade; public interface FacadeFacadeUtil{ void render(T type); static void sop(Object object) { System.out.println(object); } }
package org.feng.zoo.client.facade;
import org.feng.zoo.client.ZooManager;
import java.util.Map;
public class FacadeUtil {
private FacadeUtil() {
}
private static final Map> FACADE_MAP = Map.ofEntries(
Map.entry(0, new MainFacade()),
Map.entry(1, new ListFacade()),
Map.entry(2, new SearchAnimalFacade()),
Map.entry(3, new AddAnimalFacade()),
Map.entry(4, new UpdateAnimalFacade()),
Map.entry(5, new DeleteAnimalFacade())
);
public static Facade getByIndex(Integer index) {
return FACADE_MAP.get(index);
}
}
ListFacade
package org.feng.zoo.client.facade; import org.feng.zoo.client.ZooManager; import static org.feng.zoo.client.facade.Facade.sop; public class ListFacade implements FacadeMainFacade{ private void init() { sop("***************************动物园管理系统**************************"); sop("********************已选择 [1] 列出所有的动物***********************"); } @Override public void render(ZooManager zooManager) { init(); zooManager.listAnimals(); } }
package org.feng.zoo.client.facade; import org.feng.zoo.client.ZooManager; import org.feng.zoo.util.PrintUtil; import static org.feng.zoo.client.facade.Facade.sop; public class MainFacade implements FacadeSearchAnimalFacade{ public static final Integer INDEX = 0; private void init() { sop("***********************欢迎来到动物园管理系统***********************"); sop("******************************主界面******************************"); sop("****t 1. 列出所有的动物"); sop("****t 2. 查找动物信息"); sop("****t 3. 增加动物信息"); sop("****t 4. 修改动物信息"); sop("****t 5. 删除动物信息"); sop("****t (Tips)请选择数字序号,进入对应的功能!"); } @Override public void render(ZooManager zooManager) { init(); // 从键盘接收一个数字 String selectedIndex = PrintUtil.in("请输入:"); Integer integer = PrintUtil.toIntIndex(selectedIndex); // 根据数字映射到不同的面板上 zooManager.setFacade(FacadeUtil.getByIndex(integer)); } }
package org.feng.zoo.client.facade; import org.feng.zoo.animals.AnimalFactory; import org.feng.zoo.animals.BaseAnimal; import org.feng.zoo.animals.enums.AnimalTypeEnum; import org.feng.zoo.animals.enums.SexEnum; import org.feng.zoo.client.ZooManager; import org.feng.zoo.util.PrintUtil; import java.util.List; import static org.feng.zoo.client.facade.Facade.sop; public class SearchAnimalFacade implements FacadeUpdateAnimalFacade{ private void init() { sop("***************************动物园管理系统**************************"); sop("********************已选择 [2] 查找动物信息***********************"); } @Override public void render(ZooManager zooManager) { init(); sop("(Tips)可选择的动物类型如下:"); // 列出动物类型 zooManager.listAnimalTypes(); String animalTypeIndex = PrintUtil.in("请选择要查找的动物的类型序号"); AnimalTypeEnum animalType = zooManager.getAnimalTypeByIndex(PrintUtil.toIntIndex(animalTypeIndex)); // 动物名称 String animalName = PrintUtil.in("请输入要查找的动物名字"); sop("(Tips)可选择的动物性别如下:"); // 列出动物性别 zooManager.listAnimalSex(); String animalSexIndex = PrintUtil.in("请选择要查找的动物的性别序号"); SexEnum animalSex = zooManager.getAnimalSexByIndex(PrintUtil.toIntIndex(animalSexIndex)); BaseAnimal animal = AnimalFactory.newAnimal(animalType, animalName, animalSex); if (animal == null) { sop("不支持的动物类型"); return; } List resultList = zooManager.search(animal); zooManager.listAnimals(resultList); } }
package org.feng.zoo.client.facade; import org.feng.zoo.animals.AnimalFactory; import org.feng.zoo.animals.BaseAnimal; import org.feng.zoo.animals.enums.AnimalTypeEnum; import org.feng.zoo.animals.enums.SexEnum; import org.feng.zoo.client.ZooManager; import org.feng.zoo.util.PrintUtil; import static org.feng.zoo.client.facade.Facade.sop; public class UpdateAnimalFacade implements FacadeManager{ private void init() { sop("***************************动物园管理系统**************************"); sop("********************已选择 [4] 修改动物信息***********************"); } @Override public void render(ZooManager zooManager) { init(); sop("可供修改的动物列表如下:"); zooManager.listAnimals(); String needUpdateIndex = PrintUtil.in("请选择对应序号:"); BaseAnimal oldAnimal = zooManager.getByIndex(PrintUtil.toIntIndex(needUpdateIndex)); if (oldAnimal == null) { sop("不存在的动物序号"); } sop("(Tips)可的选择的动物类型如下:"); // 列出动物类型 zooManager.listAnimalTypes(); String animalTypeIndex = PrintUtil.in("请选择要修改的动物的类型序号"); AnimalTypeEnum animalType = zooManager.getAnimalTypeByIndex(PrintUtil.toIntIndex(animalTypeIndex)); // 动物名称 String animalName = PrintUtil.in("请输入要修改的动物名字"); sop("(Tips)可选择的动物性别如下:"); // 列出动物性别 zooManager.listAnimalSex(); String animalSexIndex = PrintUtil.in("请选择要修改的动物的性别序号"); SexEnum animalSex = zooManager.getAnimalSexByIndex(PrintUtil.toIntIndex(animalSexIndex)); BaseAnimal newAnimal = AnimalFactory.newAnimal(animalType, animalName, animalSex); zooManager.update(oldAnimal, newAnimal); newAnimal.move(); sop("修改成功!"); } }
package org.feng.zoo.client; import org.feng.zoo.client.facade.Facade; import java.util.List; public interface ManagerZooClient{ void add(T type); boolean delete(T type); void update(T old, T newInstance); List search(T type); void setFacade(Facade facade); }
package org.feng.zoo.client;
import org.feng.zoo.animals.BaseAnimal;
import org.feng.zoo.animals.Cat;
import org.feng.zoo.animals.Dog;
import org.feng.zoo.animals.Fish;
import org.feng.zoo.animals.enums.SexEnum;
import org.feng.zoo.client.facade.FacadeUtil;
import org.feng.zoo.util.PrintUtil;
import java.util.ArrayList;
import java.util.List;
public class ZooClient {
public static void main(String[] args) {
ZooClient zooClient = new ZooClient();
ZooManager zooManager = new ZooManager(zooClient.init());
boolean isContinue = true;
while (isContinue) {
String command = PrintUtil.in("是否继续使用其他功能(n表示退出,其他表示继续!)");
if (!"n".equals(command)) {
// 设置主面板
zooManager.setFacade(FacadeUtil.getByIndex(0));
continue;
}
isContinue = false;
}
System.out.println("已经成功退出系统!");
}
private List init() {
List animals = new ArrayList<>(30);
animals.add(new Dog("愣娃", SexEnum.MALE));
animals.add(new Cat("汤姆", SexEnum.FEMALE));
animals.add(new Cat("崽崽", SexEnum.MALE));
animals.add(new Cat("胖橘", SexEnum.FEMALE));
animals.add(new Fish("小金", SexEnum.FEMALE));
animals.add(new Fish("尼莫", SexEnum.MALE));
animals.add(new Fish("泡泡", SexEnum.MALE));
return animals;
}
}
ZooManager
package org.feng.zoo.client; import org.feng.zoo.animals.BaseAnimal; import org.feng.zoo.animals.enums.AnimalTypeEnum; import org.feng.zoo.animals.enums.SexEnum; import org.feng.zoo.client.facade.Facade; import org.feng.zoo.client.facade.FacadeUtil; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.function.Predicate; public class ZooManager implements ManagerPrintUtil{ private final List animalList; private Facade facade; public ZooManager(List animalList) { this.animalList = Objects.requireNonNullElseGet(animalList, () -> new ArrayList<>(20)); setFacade(FacadeUtil.getByIndex(0)); } public void listAnimals() { listAnimals(animalList); } public void listAnimals(List animalList) { sop("序号tt 动物类型 tt 动物名称 tt 性别"); int size = animalList.size(); String listPattern = "%stt %s tt %s tt %s"; for (int i = 0; i < size; i++) { BaseAnimal animal = animalList.get(i); sop(String.format(listPattern, (i + 1), animal.getType().getChineseDesc(), animal.getName(), animal.getSex().getDesc())); } } public void listAnimalTypes() { AnimalTypeEnum.list(); } public AnimalTypeEnum getAnimalTypeByIndex(Integer index) { AnimalTypeEnum[] animalTypeEnums = AnimalTypeEnum.values(); if (index < 0 || index > animalTypeEnums.length) { return null; } return animalTypeEnums[index - 1]; } public void listAnimalSex() { SexEnum.list(); } public SexEnum getAnimalSexByIndex(Integer index) { SexEnum[] animalSexEnums = SexEnum.values(); if (index < 0 || index > animalSexEnums.length) { return null; } return animalSexEnums[index - 1]; } public BaseAnimal getByIndex(Integer selectedIndex) { if (selectedIndex < 0 || selectedIndex > animalCount()) { return null; } return animalList.get(selectedIndex - 1); } @SafeVarargs private List filters(Predicate ... predicates) { if (predicates == null || predicates.length == 0) { return animalList; } List resultList = new ArrayList<>(animalList.size()); for (BaseAnimal animal : animalList) { boolean filtersSuccess = true; for (Predicate predicate : predicates) { filtersSuccess = predicate.test(animal) & filtersSuccess; } if (filtersSuccess) { resultList.add(animal); } } return resultList; } public int animalCount() { return animalList.size(); } private static void sop(String printString) { System.out.println(printString); } @Override public void add(BaseAnimal animal) { animalList.add(animal); } @Override public boolean delete(BaseAnimal animal) { return animalList.remove(animal); } public boolean delete(int selectedIndex) { if (selectedIndex < 0 || selectedIndex > animalCount()) { return false; } return animalList.remove(selectedIndex - 1) != null; } @Override public void update(BaseAnimal oldAnimal, BaseAnimal newAnimal) { animalList.stream() .filter(animal -> Objects.equals(animal, oldAnimal)) .forEach(animal -> { animal.setName(newAnimal.getName()); animal.setType(newAnimal.getType()); animal.setSex(newAnimal.getSex()); }); } @Override public List search(BaseAnimal animal) { if (Objects.nonNull(animal.getType()) && Objects.nonNull(animal.getName()) && Objects.nonNull(animal.getSex())) { return filters(instance -> instance.getName().contains(animal.getName()), instance -> instance.getType().equals(animal.getType()), instance -> instance.getSex().equals(animal.getSex()) ); } if (Objects.nonNull(animal.getType()) && Objects.nonNull(animal.getName())) { return filters(instance -> instance.getName().contains(animal.getName()), instance -> instance.getType().equals(animal.getType()) ); } return animalList; } @Override public void setFacade(Facade facade) { this.facade = facade; // 渲染场景 this.facade.render(this); } public Facade getFacade() { return facade; } }
package org.feng.zoo.util;
import org.feng.zoo.client.facade.MainFacade;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class PrintUtil {
private static final BufferedReader BUFFERED_READER = new BufferedReader(new InputStreamReader(System.in));
public static String in(String tips) {
// 输出提示词
System.out.println(tips);
String result = null;
try {
// 接收一行输入
result = BUFFERED_READER.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
public static Integer toIntIndex(String selectedIndex) {
try {
return Integer.parseInt(selectedIndex);
} catch (Exception e) {
System.err.println("无效的输入!");
return MainFacade.INDEX;
}
}
}
本次的运行效果
***********************欢迎来到动物园管理系统*********************** ******************************主界面****************************** **** 1. 列出所有的动物 **** 2. 查找动物信息 **** 3. 增加动物信息 **** 4. 修改动物信息 **** 5. 删除动物信息 **** (Tips)请选择数字序号,进入对应的功能! 请输入: 1 ***************************动物园管理系统************************** ********************已选择 [1] 列出所有的动物*********************** 序号 动物类型 动物名称 性别 1 狗 愣娃 雄性 2 猫 汤姆 雌性 3 猫 崽崽 雄性 4 猫 胖橘 雌性 5 鱼 小金 雌性 6 鱼 尼莫 雄性 7 鱼 泡泡 雄性 是否继续使用其他功能(n表示退出,其他表示继续!) y ***********************欢迎来到动物园管理系统*********************** ******************************主界面****************************** **** 1. 列出所有的动物 **** 2. 查找动物信息 **** 3. 增加动物信息 **** 4. 修改动物信息 **** 5. 删除动物信息 **** (Tips)请选择数字序号,进入对应的功能! 请输入: 2 ***************************动物园管理系统************************** ********************已选择 [2] 查找动物信息*********************** (Tips)可选择的动物类型如下: 序号 动物类型 1 猫 2 狗 3 鱼 4 猴子 5 大象 6 鸟 请选择要查找的动物的类型序号 1 请输入要查找的动物名字 汤姆 (Tips)可选择的动物性别如下: 序号 动物性别 1 雄性 2 雌性 请选择要查找的动物的性别序号 2 序号 动物类型 动物名称 性别 1 猫 汤姆 雌性 是否继续使用其他功能(n表示退出,其他表示继续!) 2 ***********************欢迎来到动物园管理系统*********************** ******************************主界面****************************** **** 1. 列出所有的动物 **** 2. 查找动物信息 **** 3. 增加动物信息 **** 4. 修改动物信息 **** 5. 删除动物信息 **** (Tips)请选择数字序号,进入对应的功能! 请输入:结论
首先在程序复杂程度上,本次明显能好理解些。
没有大量的switch、if判断。
代码也更加清爽。



