实现赛博朋克宠物商店

你是宇宙中,最有名的一家Cyberpunk宠物商店的老板,而你的雇员全是你所发明的机器人,他们是——商店总管李、宠物看护者、宠物Tony哥、宠物饲喂猿、宠物服装师、宠物驯化王……,你的顾客来着宇宙的每一个角落。

显然你的宠物店规模和业务量都很大,为了摸索更正当的经营形式,你打算通过软件模仿你的商店,在未来(当初不必做)通过剖析商店日志找到优化计划。

商店总管李:负责与客户交换,帮忙客户抉择相应的服务,并安顿其余机器人执行相应我的项目。服从你的指令,汇报宠物店在某段时间产生了什么。

宠物看护者:负责宠物的寄养,宠物客人将宠物交给商店,寄养,设定寄养工夫,到时告诉认领(与上次不同,这次要实现真正的计时,并且实现真正到时揭示,能够用程序中的一秒模仿事实世界中的一小时(或十分钟))。

宠物Tony哥:负责给宠物的毛发洗、剪、吹、拉、烫、染、焗,这里使用装璜者模式,实现对宠物毛发的装璜。

宠物饲喂猿:负责给宠物喂食,当宠物饿的时候(过了一段时间就会饿)。

宠物服装师:负责给宠物穿各种各样的服饰,色彩能够是红、橙、黄、绿、青、蓝、紫(也不肯定都要),品种能够是帽、鞋、裤、褂、裙,材质能够是棉、麻、丝、绒、革;同Tony哥一样,负责对宠物衣着装璜,应用装璜者模式。

为了商店收益最大化,每一类的机器人你都发明了很多很多个(总是够用),但总管李只有一个,当总管李服务了顾客抉择了相应的生产我的项目,相应的我的项目立马转到后盾执行,这样总管李又能够马上服务新的客人。每一项我的项目都有规范的执行流程,因而每个同类我的项目(例如,所有宠物染色的工夫,戴帽的工夫)执行的工夫能够看作是雷同的,不同类我的项目执行工夫不同。为了分明商店的运行状况,你要求每个机器人把本人的每一步操作写到商店日志里,当然这也是私下进行的。

你总是很忙,忙着创造新的机器人,没有工夫看商店日志,因而,你能够要求总管李汇报商店在某一段时间产生了哪些事。

思路剖析

利用单例模式建设Manager类接管顾客服务信息,在CyberpunkPetShop类内实例化Manager并建设两个线程,利用线程通信实现有限次顾客进入,线程种利用state决定与判断是否不再接管新的顾客并终止线程,Manager类内的run办法利用接管到的宠物和服务信息实例化Pet类,并开启Pet服务线程,在Pet类内定义了几个服务入口,一个是蕴含了看护和喂食的办法Mind(),一个是实现发型设计的designHair办法,还有一个是实现服装设计的designCostume办法。通过实例化Pet类并开启办法实现宠物服务。其中继承抽象类Hair的未装璜类为SimpleHair类,装璜器类为HairDecorator,HairDecorator有PermHair,PullHair等具体实现,继承抽象类Costume类的未装璜类有Skirt,Pant等,装璜器类为CostumeColor,CostumeColor有对应Black,Brown等具体实现。这里利用装璜器模式能够实现繁难的服装和发型搭配。程序运行过程中因为是多线程运行,所以采纳了日志框架log4j进行商店服务过程信息的记录。程序在不再接管新的顾客之后对日志进行一次输入。残缺日志能够在对应info.log中查看。

程序框架:


几个次要的类:

接管顾客服务要求的Manager类:

要害:单例模式中的饿汉式,线程通信

package com.CyberpunkPetShop.java;import org.apache.log4j.Logger;import java.io.BufferedReader;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;import java.util.Scanner;//主管李类,负责解决顾客需要public class ManagerLi implements Runnable {    //单例模式创立主管李    private boolean state;//标记是否不再接管新的顾客    private int signal;//不再接管新的顾客时收回的信号标记    private int customerNum;//顾客编号    private static Logger logger = Logger.getLogger(ManagerLi.class);    private static ManagerLi managerLi = new ManagerLi();//只有static的成员能力在没有创建对象时进行初始化    private ManagerLi(){        state = true;        customerNum = 1;    }    public static ManagerLi getInstance() {        return managerLi;    }    public static void showShopLog(){        try {            BufferedReader br = new BufferedReader(new FileReader("info.log"));            String s;            while((s = br.readLine()) != null){                System.out.println(s);            }        } catch (FileNotFoundException e) {            logger.error(e.getMessage());        } catch (IOException e) {            logger.error(e.getMessage());        }    }    @Override    public void run() {        while(true){            synchronized (managerLi) {                notify();                if(state) {                    System.out.println("欢送" + customerNum + "号顾客来到赛博朋克宠物店!我是总管李!上面将由我为你安顿服务!");                    logger.info("第" + customerNum + "位顾客进入商店");                    customerNum++;                    System.out.println("请输出你的宠物的名称:");                    Scanner scan = new Scanner(System.in);                    String p = scan.next();                    scan.nextLine();                    Pet pet = new Pet();                    pet.setName(p);                    System.out.println("这是服务菜单:\n1.寄养宠物\n2.为宠物装扮头发\n3.为宠物装璜衣服\n0.抉择服务结束\n请进行抉择:(每个服务以换行离开)");                    boolean[] c = new boolean[4];//服务抉择                    boolean[] h = new boolean[5];//头发装璜抉择                    boolean[] w_t = new boolean[5];//服装类型抉择                    boolean[] w_c = new boolean[5];//服装色彩抉择                    while (true) {                        int choice = new Scanner(System.in).nextInt();                        if (choice == 0) break;                        c[choice] = true;                    }                    //若顾客想要理发                    if(c[2]) {                        h[0] = true;                        System.out.println("输出1进行装璜头发抉择,输出其余只进行简略理发");                        var ch = new Scanner(System.in).next();                        if (ch.equals("1")) {                            System.out.println("装璜头发服务菜单:\n1.染发\n2.烫发\n3.洗发\n4.拉发");                            int ch1 = new Scanner(System.in).nextInt();                            h[ch1] = true;                        }                    }                    //若顾客想要装璜服装                    if(c[3]){                        System.out.println("进行服装类型抉择:\n1.帽子\n2.裤子\n3.裙子\n4.毛衣");                        Scanner in = new Scanner((System.in));                        int ch;                        ch = in.nextInt();                        w_t[ch] = true;                        System.out.println("进行服装色彩抉择:\n1.红色\n2.黄色\n3.彩色\n4.棕色");                        ch = in.nextInt();                        w_c[ch] = true;                    }                    pet.setService(c);                    pet.setHairService(h);                    pet.setCostumeTypeService(w_t);                    pet.setCostumeColorService(w_c);                    Thread t = new Thread(pet);                    t.setName(pet.getName() + "服务线程");                    t.start();                    try {                        wait();                        if(state) {                            System.out.println("输出1持续接收顾客,输出0不再接收顾客:");                            int choose = new Scanner(System.in).nextInt();                            if (choose == 0) state = false;                        }                    } catch (InterruptedException e) {                        logger.error(e.getMessage());                    }                }else{                    signal++;                    if(signal == 1) {                        System.out.println("本店明天不再接收新的顾客!");                        System.out.println("期待残余服务完结......");                        logger.info("赛博朋克商店明天不再接收新的顾客");                    }                    break;                }            }        }    }}

装璜器类CostumeColor类及HairDecorator

利用装璜器模式进行繁难的搭配设计

package com.Costume.java;//服装色彩装璜类,利用装璜器模式设计头发public class CostumeColor extends Costume{    private Costume costume;    public CostumeColor(Costume obj){        this.costume = obj;    }    @Override    public String getDepression() {        return depression + costume.getDepression();    }}
package com.Hair.java;//头发装璜类,利用装璜器模式设计发型public class HairDecorator extends Hair{    private Hair hair;    public HairDecorator(Hair obj){        this.hair = obj;    }    public String getDepression(){        return depression + "+" + hair.depression;    }}

日志信息配置:

### 设置###log4j.rootLogger = INFO, A, B### 输入INFO级别以上的日志到=D://@java/ForthComputerPractice/info.log ###log4j.appender.A = org.apache.log4j.FileAppenderlog4j.appender.A.File = D://@java/ForthComputerPractice/info.loglog4j.appender.A.Append = falselog4j.appender.A.Threshold = INFOlog4j.appender.A.layout = org.apache.log4j.PatternLayoutlog4j.appender.A.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n### 输入WARN级别以上的日志到=D:/@java/ForthComputerPractice/error.log ###log4j.appender.B = org.apache.log4j.FileAppenderlog4j.appender.B.File =D://@java/ForthComputerPractice/error.loglog4j.appender.B.Append = falselog4j.appender.B.Threshold = ERRORlog4j.appender.B.layout = org.apache.log4j.PatternLayoutlog4j.appender.B.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

须要残缺源码可在github或者gitee进行clone:

https://gitee.com/jiang-zhihang/cyberpunk-pet-shop.git
https://github.com/akynazh/CyberpunkPetShop.git

后续发现有问题会继续进行版本更新。