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

前言

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章