程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

西电Java上机作业—实现赛博朋克宠物商店

发布于2021-06-12 15:22     阅读(114)     评论(0)     点赞(18)     收藏(3)


实现赛博朋克宠物商店

你是宇宙中,最有名的一家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.FileAppender
log4j.appender.A.File = D://@java/ForthComputerPractice/info.log
log4j.appender.A.Append = false
log4j.appender.A.Threshold = INFO
log4j.appender.A.layout = org.apache.log4j.PatternLayout
log4j.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.FileAppender
log4j.appender.B.File =D://@java/ForthComputerPractice/error.log
log4j.appender.B.Append = false
log4j.appender.B.Threshold = ERROR
log4j.appender.B.layout = org.apache.log4j.PatternLayout
log4j.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

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

原文链接:https://blog.csdn.net/akyna/article/details/117699281



所属网站分类: 技术文章 > 博客

作者:快起来搬砖啦

链接:http://www.javaheidong.com/blog/article/222450/1765683205ecd2a353b9/

来源:java黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

18 0
收藏该文
已收藏

评论内容:(最多支持255个字符)