文章目录

  • 前言
  • 项目结构
  • java 代码
    • AbstractAnimal
    • Cat
    • Dog
    • Leg
    • Swim
    • ZooManager
    • RunTest
    • Client
  • 程序运行
  • 结果展示
  • 最后
  • 修改
    • Client 中的main方法

前言

原文链接:https://blog.csdn.net/FBB360JAVA/article/details/79256570
本文重在code review。
实现的只是一个简易的管理系统,控制台输入、输入。以及增删改查等操作。

另外请参见:使用门面设计模式+简单工厂改造的新的一版管理系统。
https://blog.csdn.net/FBB360JAVA/article/details/124529049

项目结构



其中 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;}/*** 深克隆:需要序列化。* 为后期扩展而写(可能会用到,目前程序中没有使用)*/@Deprecatedpublic 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());}@Overridepublic String toString() {return String.join("\t\t", name, type);}@Overridepublic 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);}@Overridepublic 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);}@Overridepublic 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);}@Overridepublic 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);// trueSystem.out.println(manager.containsAnimal(cat));// 修改动物信息manager.updateAnimal(cat, new Cat("小小刘"));// 删除:trueSystem.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("++++++++++++++++++++++++++++");}}

简易的动物园管理系统之Java8流式API的重构代码(使用 状态设计模式)相关推荐

  1. 简易的动物园管理系统之Java8流式API的重构代码(使用 门面设计模式)

    文章目录 前言 之前的文章 本次的源码 AnimalTypeEnum SexEnum Animal AnimalFactory BaseAnimal Bird Cat Dog Fish AddAnim ...

  2. Jackson高级操作————流式API与JsonGenerator、JsonParser

    引言 继<Jackson快速入门>之后的高级相关操作. Jackson提供了一种对于性能要求应用程序操作json更加高效的方式--流式API,这种方式开销小,性能高,因此,如果应用程序或者 ...

  3. 使用JackJSON 流式API 创建JSON串【学习记录】

    教程网址:Jackson流式API 目标JSON串 原始JSON串 核心代码 思路:先将原始JSON串生成对应的对象,获取到其数据 package com.run.runlpwebdemo.utils ...

  4. java流式api,Java 8 中流式API性能基准测试

    测试代码 package hello.test; import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.runner.Runner; ...

  5. Java8 流式递归树形菜单

    Web端常用界面 树形菜单 1. 说明 2. 表设计 3. 普通递归 4. 流式递归语法糖 1. 说明 树形菜单在web后台管理系统, 权限管理中基本上很容易见到.如:csdn的个人后台管理系统. 只 ...

  6. linux fifo数据流,在linux / bash中使用非阻塞FIFO流式传输视频(示例代码)

    我正在努力实现以下目标: 将我的Raspberry Pi相机中的视频写入磁盘,不受任何流式干扰 通过网络流式传输相同的视频优化延迟 重要的是流不会干扰正在写入磁盘的视频,因为网络连接可能不稳定,例如W ...

  7. 简易的动物园管理系统

    #动物园管理 有猫,鸭子,鱼等动物,他们有一个共同的父类–Animal,共同的属性是动物的名字,父类中有一个抽象方法. 2个接口,一个是获得腿的条数,一个是Swim. 一个管理类,用来进行增删改查操作 ...

  8. JAVA8流式编程总结(持续更新)

    1.分组 List<TaskHeaderPO> tasks = List<TaskVO> subTasks = tasks.stream().map(task -> {T ...

  9. java 流常用接口_java 8新特性5--使用集合流式API

    PS:向公众号发送关键字可以搜索文章哦! 使用集合的流式API 直接上代码了,常用api都有了,要点都在注释中 苹果类: packagejava8.stream;/***@authorqiang.xi ...

最新文章

  1. 浅尝Windows Server 2016——Container 容器:部署
  2. basler相机 ip linux,Basler 相机启动运行程序, Basler IP相机软件 - 其他软件 | Basler
  3. 如何检查服务是否在Android上运行?
  4. nginx实现请求的负载均衡 + keepalived实现nginx的高可用
  5. JS配合css实现slide文字框缩放伸展效果
  6. Python之30秒就能学会的漂亮短程序代码
  7. Golang中使用kafka
  8. 微信小程序使用template模板
  9. php 安全基础 第七章 验证与授权 密码嗅探
  10. 把SAP Cloud for Customer嵌入到IFrame里
  11. windows中VS卸载opencv配置,重新安装其他版本
  12. glass fish_Glass Fish 4.0.1中的Jersey SSE功能
  13. 你的鼠标有多快-小游戏
  14. dorado7-发布
  15. 2018-04-08椭圆曲线测试程序
  16. 还原卡及还原精灵的破解
  17. 帆软报表更新到服务器控件展示不出来_如何报表控件FineReport实现自定义附件处理...
  18. Android EditText去掉下划线
  19. 深度学习-感知机模型---思路图解+python代码
  20. AutoSAR系列讲解(入门篇)5.2-描述文件

热门文章

  1. jqprint打印的简单使用
  2. 练习:班里有人和我同生日难吗?(概率probability、蒙特卡洛随机模拟法)
  3. RNN语音分类-普通话广东话分类
  4. 对上海物流中转新措施作架构分析
  5. [Linux]设置swap交换空间
  6. web---盒子模型(思维导图)
  7. 数据建模实战,Smartbi带你玩转购物篮分析
  8. 作为开发者,你天天加班,做的累不累?
  9. c语言中标签的作用域,C语言:goto标签的作用域到底是什么(疑惑)?
  10. 盘点一道Python列表基础题目