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

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

文章目录
  • 前言
  • 之前的文章
  • 本次的源码
    • AnimalTypeEnum
    • SexEnum
    • Animal
    • AnimalFactory
    • BaseAnimal
    • Bird
    • Cat
    • Dog
    • Fish
    • AddAnimalFacade
    • DeleteAnimalFacade
    • Facade
    • FacadeUtil
    • ListFacade
    • MainFacade
    • SearchAnimalFacade
    • UpdateAnimalFacade
    • Manager
    • ZooClient
    • ZooManager
    • PrintUtil
  • 本次的运行效果
  • 结论
  • 优化思路
    • 1 使用反射优化工厂方法
    • 2 模仿 Spring 框架的bean管理方式

前言

鉴于各位小伙伴对这类入门级程序的热忱,本人对于之前的重构,再次重构。
本次设计,用到了简单工厂设计模式、门面设计模式,抽象类、接口、集合容器的增删改查、遍历集合等java知识点。

之前的文章

初版:
https://blog.csdn.net/FBB360JAVA/article/details/79256570

简易的动物园管理系统之Java8流式API的重构代码(使用 状态设计模式)
https://blog.csdn.net/FBB360JAVA/article/details/105627691

本次的源码

AnimalTypeEnum
package org.feng.zoo.animals.enums;

/**
 * 动物类型枚举
 *
 * @version v1.0
 * @author: fengjinsong
 * @date: 2022年05月01日 10时18分
 */
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("序号\t\t 动物类型");
        String animalTypePattern = "%s\t\t%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;

/**
 * 动物性别枚举
 *
 * @version v1.0
 * @author: fengjinsong
 * @date: 2022年05月01日 12时59分
 */
public enum SexEnum {
    /**
     * 动物性别
     */
    MALE("雄性"), FEMALE("雌性");
    private final String desc;

    SexEnum(String desc) {
        this.desc = desc;
    }

    /**
     * 列出所有的动物性别
     */
    public static void list() {
        System.out.println("序号\t\t 动物性别");
        String animalSexPattern = "%s\t\t%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;

/**
 * 动物接口:所有动物类都要实现这个接口
 *
 * @version v1.0
 * @author: fengjinsong
 * @date: 2022年05月01日 10时17分
 */
public interface Animal {
    /**
     * 获取动物类型
     *
     * @return 动物类型枚举
     */
    AnimalTypeEnum getType();

    /**
     * 获取动物名称
     *
     * @return 动物名字
     */
    String getName();

    SexEnum getSex();

    /**
     * 移动:比如狗用4条腿跑,鸟用翅膀飞,鱼在水里游
     */
    void move();
}

AnimalFactory
package org.feng.zoo.animals;

import org.feng.zoo.animals.enums.AnimalTypeEnum;
import org.feng.zoo.animals.enums.SexEnum;

/**
 * 动物工厂,通过它获取动物实例
 *
 * @version v1.0
 * @author: fengjinsong
 * @date: 2022年05月01日 15时22分
 */
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;

/**
 * 动物基类:设计为抽象类,不允许直接创建对象,需要使用时,创建其子类实例
 *
 * @version v1.0
 * @author: fengjinsong
 * @date: 2022年05月01日 10时33分
 */
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 \t\t %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;

/**
 * 鸟
 *
 * @version v1.0
 * @author: fengjinsong
 * @date: 2022年05月01日 10时30分
 */
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;

/**
 * 猫
 *
 * @version v1.0
 * @author: fengjinsong
 * @date: 2022年05月01日 10时29分
 */
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;

/**
 * 狗
 *
 * @version v1.0
 * @author: fengjinsong
 * @date: 2022年05月01日 10时30分
 */
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;

/**
 * 鱼
 *
 * @version v1.0
 * @author: fengjinsong
 * @date: 2022年05月01日 10时32分
 */
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;

/**
 * 增加动物面板
 *
 * @author Administrator
 */
public class AddAnimalFacade implements Facade<ZooManager> {

    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("增加动物成功!");
    }
}
DeleteAnimalFacade
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;

/**
 * 删除动物面板
 *
 * @version v1.0
 * @author: fengjinsong
 * @date: 2022年05月01日 15时46分
 */
public class DeleteAnimalFacade implements Facade<ZooManager> {
    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("删除失败!");
        }
    }
}


Facade
package org.feng.zoo.client.facade;

/**
 * 外观模式
 *
 * @version v1.0
 * @author: fengjinsong
 * @date: 2022年05月01日 13时57分
 */
public interface Facade<T> {
    /**
     * 渲染场景
     */
    void render(T type);

    /**
     * 打印参数到控制台
     *
     * @param object 参数
     */
    static void sop(Object object) {
        System.out.println(object);
    }
}

FacadeUtil
package org.feng.zoo.client.facade;

import org.feng.zoo.client.ZooManager;

import java.util.Map;

/**
 * 门面的工具类
 *
 * @version v1.0
 * @author: fengjinsong
 * @date: 2022年05月01日 14时28分
 */
public class FacadeUtil {
    private FacadeUtil() {
    }

    private static final Map<Integer, Facade<ZooManager>> 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<ZooManager> 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;

/**
 * 列出所有动物的门面
 *
 * @version v1.0
 * @author: fengjinsong
 * @date: 2022年05月01日 14时36分
 */
public class ListFacade implements Facade<ZooManager> {

    private void init() {
        sop("***************************动物园管理系统**************************");
        sop("********************已选择 [1] 列出所有的动物***********************");
    }

    @Override
    public void render(ZooManager zooManager) {
        init();
        zooManager.listAnimals();
    }
}


MainFacade
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;

/**
 * 主面板
 *
 * @author Administrator
 */
public class MainFacade implements Facade<ZooManager> {

    /**
     * 主面板的索引是 0
     */
    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));
    }
}

SearchAnimalFacade
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;

/**
 * 查找动物面板
 *
 * @version v1.0
 * @author: fengjinsong
 * @date: 2022年05月01日 15时45分
 */
public class SearchAnimalFacade implements Facade<ZooManager> {
    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<BaseAnimal> resultList = zooManager.search(animal);
        zooManager.listAnimals(resultList);
    }
}

UpdateAnimalFacade
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;

/**
 * 更新动物面板
 *
 * @author Administrator
 */
public class UpdateAnimalFacade implements Facade<ZooManager> {
    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("修改成功!");
    }
}

Manager

package org.feng.zoo.client;

import org.feng.zoo.client.facade.Facade;

import java.util.List;

/**
 * 管理者接口
 *
 * @version v1.0
 * @author: fengjinsong
 * @date: 2022年05月01日 13时17分
 */
public interface Manager<T, R> {
    /**
     * 增加
     *
     * @param type 某类型
     */
    void add(T type);

    /**
     * 删除
     *
     * @param type 某类型
     * @return 删除成功返回true;否则返回false
     */
    boolean delete(T type);

    /**
     * 更新
     *
     * @param old         旧值
     * @param newInstance 新实例
     */
    void update(T old, T newInstance);

    /**
     * 查找
     *
     * @param type 某类型
     * @return 查找结果
     */
    List<T> search(T type);

    /**
     * 设置门面
     *
     * @param facade 具体的门面,根据门面设置场景
     */
    void setFacade(Facade<R> facade);
}

ZooClient
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;

/**
 * 动物园客户端管理界面
 *
 * @version v1.0
 * @author: fengjinsong
 * @date: 2022年05月01日 10时23分
 */
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<BaseAnimal> init() {
        List<BaseAnimal> 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;

/**
 * 动物园管理者
 *
 * @version v1.0
 * @author: fengjinsong
 * @date: 2022年05月01日 11时27分
 */
public class ZooManager implements Manager<BaseAnimal, ZooManager> {

    /**
     * 动物列表
     */
    private final List<BaseAnimal> animalList;

    /**
     * 门面场景
     */
    private Facade<ZooManager> facade;

    public ZooManager(List<BaseAnimal> animalList) {
        this.animalList = Objects.requireNonNullElseGet(animalList, () -> new ArrayList<>(20));
        setFacade(FacadeUtil.getByIndex(0));
    }


    public void listAnimals() {
        listAnimals(animalList);
    }

    public void listAnimals(List<BaseAnimal> animalList) {
        sop("序号\t\t 动物类型 \t\t 动物名称 \t\t 性别");
        int size = animalList.size();

        String listPattern = "%s\t\t %s \t\t %s \t\t %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];
    }

    /**
     * 通过面板中的序号查找对应的动物信息
     *
     * @param selectedIndex 选中的序号
     * @return 通过序号得到的索引
     */
    public BaseAnimal getByIndex(Integer selectedIndex) {
        if (selectedIndex < 0 || selectedIndex > animalCount()) {
            return null;
        }
        return animalList.get(selectedIndex - 1);
    }

    /**
     * 通过任意过滤条件,获得动物列表
     *
     * @param predicates 条件
     * @return 动物列表
     */
    @SafeVarargs
    private List<BaseAnimal> filters(Predicate<BaseAnimal>... predicates) {
        if (predicates == null || predicates.length == 0) {
            return animalList;
        }

        List<BaseAnimal> resultList = new ArrayList<>(animalList.size());
        for (BaseAnimal animal : animalList) {
            boolean filtersSuccess = true;
            for (Predicate<BaseAnimal> predicate : predicates) {
                filtersSuccess = predicate.test(animal) & filtersSuccess;
            }

            if (filtersSuccess) {
                resultList.add(animal);
            }
        }

        return resultList;
    }


    /**
     * 当前动物园内动物的数量
     *
     * @return 动物的数量
     */
    public int animalCount() {
        return animalList.size();
    }

    /**
     * 输出字符串到控制台
     *
     * @param printString 要输出的字符串
     */
    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());
                });
    }

    /**
     * 精准查找:根据名字(模糊匹配)、类型、性别查找
     *
     * @param animal 动物
     * @return 符合条件的动物
     */
    @Override
    public List<BaseAnimal> 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<ZooManager> facade) {
        this.facade = facade;
        // 渲染场景
        this.facade.render(this);
    }

    public Facade<ZooManager> getFacade() {
        return facade;
    }
}

PrintUtil
package org.feng.zoo.util;

import org.feng.zoo.client.facade.MainFacade;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * 输出工具类
 *
 * @version v1.0
 * @author: fengjinsong
 * @date: 2022年05月01日 11时10分
 */
public class PrintUtil {
    /**
     * 字符缓冲
     */
    private static final BufferedReader BUFFERED_READER = new BufferedReader(new InputStreamReader(System.in));

    /**
     * 控制台打印tips,然后接收从键盘输入的字符串
     *
     * @param tips 提示信息
     * @return 键盘接收的字符串
     */
    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判断。
代码也更加清爽。

优化思路 1 使用反射优化工厂方法

比如,对 AnimalFactory 做处理。


package org.feng.zoo.animals;

import org.feng.zoo.animals.enums.AnimalTypeEnum;
import org.feng.zoo.animals.enums.SexEnum;

import java.lang.reflect.InvocationTargetException;
import java.util.Map;

/**
 * 动物工厂,通过它获取动物实例
 *
 * @version v1.0
 * @author: fengjinsong
 * @date: 2022年05月01日 15时22分
 */
public class AnimalFactory {

    private static final Map<AnimalTypeEnum, Class<? extends BaseAnimal>> ANIMAL_TYPE_ENUM_CLASS_MAP = Map.ofEntries(
            Map.entry(AnimalTypeEnum.CAT, Cat.class),
            Map.entry(AnimalTypeEnum.DOG, Dog.class),
            Map.entry(AnimalTypeEnum.BIRD, Bird.class),
            Map.entry(AnimalTypeEnum.FISH, Fish.class)
    );

    public static BaseAnimal newAnimal(AnimalTypeEnum type, String name, SexEnum sexEnum) {
        Class<? extends BaseAnimal> beanClass = ANIMAL_TYPE_ENUM_CLASS_MAP.getOrDefault(type, null);

        try {
            return beanClass.getDeclaredConstructor(String.class, SexEnum.class).newInstance(name, sexEnum);
        } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | NullPointerException e) {
            e.printStackTrace();
            return null;
        }
    }
}

2 模仿 Spring 框架的bean管理方式

首先需要扫描所有的 Java文件,或者自己指定一个目录。
得到这些文件后,使用类加载器加载,然后根据注解或父类、或接口判断得到自己想要的那部分类。
将得到的类缓存到Map中,不允许每次创建实例都去解析。
最终从Map中获取类信息,使用构造器去获取实例。
这里不做演示,有兴趣的童鞋参考下这里:
https://blog.csdn.net/FBB360JAVA/article/details/124437455

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/798603.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-06
下一篇 2022-05-06

发表评论

登录后才能评论

评论列表(0条)

保存