【Java】项目采用的设计模式案例
先说一下业务需要:
做电竞酒店后台系统,第一期功能有一个服务申请的消息通知功能
就是酒店用户在小程序点击服务功能,可以在后台这边查到用户的服务需要
原本设计是只需要一张表存储这些消息,但是考虑设计是SAAS结构(所有酒店数据归于一张表,根据商家ID区分各自家的数据)
数据量可能过大,组长决定把表拆分,一个服务类型一张表
这里有7个类型,就有七张消息通知表
-- aisw_e_service_renewal_msg
CREATE TABLE `aisw_e_service_renewal_msg` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`ROOM_NO` varchar(10) DEFAULT NULL COMMENT '房间号',
`MERCHANT_ID` int(11) DEFAULT NULL COMMENT '商家ID',
`SERVICE_TYPE` varchar(50) DEFAULT NULL COMMENT '服务类型(与字典表AISW_MERCHANT_DICT表关联)',
`USER_ID` int(11) DEFAULT NULL COMMENT '用户ID(与AISW_USER表关联)',
`RENEWAL_TYPE` tinyint(1) DEFAULT NULL COMMENT '续房类型(1-续住此房间 2-换房续住)',
`RENEWAL_DAY` int(11) DEFAULT NULL COMMENT '续住天数',
`ACCEPT_STATUS` tinyint(1) DEFAULT '0' COMMENT '受理状态(0-未受理 1-已受理)',
`STATUS` tinyint(1) DEFAULT '1' COMMENT '状态( 0-无效 1-有效)',
`CREATE_DATE` datetime DEFAULT NULL COMMENT '创建时间',
`UPDATE_DATE` datetime DEFAULT NULL COMMENT '更新时间',
`CREATE_BY` varchar(50) DEFAULT NULL COMMENT '创建人',
`UPDATE_BY` varchar(50) DEFAULT NULL COMMENT '更新人',
`REMARKS` text COMMENT '备注',
PRIMARY KEY (`ID`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='电竞酒店续住服务通知表'; -- aisw_e_service_clean_msg
CREATE TABLE `aisw_e_service_clean_msg` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`ROOM_NO` varchar(10) DEFAULT NULL COMMENT '房间号',
`MERCHANT_ID` int(11) DEFAULT NULL COMMENT '商家ID',
`SERVICE_TYPE` varchar(50) DEFAULT NULL COMMENT '服务类型(与字典表AISW_MERCHANT_DICT表关联)',
`USER_ID` int(11) DEFAULT NULL COMMENT '用户ID(与AISW_USER表关联)',
`CLEAN_DATE` varchar(50) DEFAULT NULL COMMENT '清扫时间',
`ACCEPT_STATUS` tinyint(1) DEFAULT '0' COMMENT '受理状态(0-未受理 1-已受理)',
`STATUS` tinyint(1) DEFAULT '1' COMMENT '状态(0-无效 1-有效)',
`CREATE_DATE` datetime DEFAULT NULL COMMENT '创建时间',
`UPDATE_DATE` datetime DEFAULT NULL COMMENT '更新时间',
`CREATE_BY` varchar(50) DEFAULT NULL COMMENT '创建人',
`UPDATE_BY` varchar(50) DEFAULT NULL COMMENT '更新人',
`REMARKS` text COMMENT '备注',
PRIMARY KEY (`ID`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='电竞酒店清扫服务通知表'; -- aisw_e_service_delivery_msg
CREATE TABLE `aisw_e_service_delivery_msg` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`ROOM_NO` varchar(10) DEFAULT NULL COMMENT '房间号',
`MERCHANT_ID` int(11) DEFAULT NULL COMMENT '商家ID',
`SERVICE_TYPE` varchar(50) DEFAULT NULL COMMENT '服务类型(与字典表AISW_MERCHANT_DICT表关联)',
`USER_ID` int(11) DEFAULT NULL COMMENT '用户ID(与AISW_USER表关联)',
`DELIVERY_TYPE` text COMMENT '配送物品类型(与AISW_MERCHANT_DICT表关联),多个以逗号隔开',
`DELIVERY_NUMS` text COMMENT '配送物品数量(以逗号分隔)',
`ACCEPT_STATUS` tinyint(1) DEFAULT '0' COMMENT '受理状态(0-未受理 1-已受理)',
`STATUS` tinyint(1) DEFAULT '1' COMMENT '状态(0-无效 1-有效)',
`CREATE_DATE` datetime DEFAULT NULL COMMENT '创建时间',
`UPDATE_DATE` datetime DEFAULT NULL COMMENT '更新时间',
`CREATE_BY` varchar(50) DEFAULT NULL COMMENT '创建人',
`UPDATE_BY` varchar(50) DEFAULT NULL COMMENT '更新人',
`REMARKS` text COMMENT '备注',
PRIMARY KEY (`ID`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='电竞酒店物品配送服务通知表'; -- aisw_e_service_fault_msg
CREATE TABLE `aisw_e_service_fault_msg` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`ROOM_NO` varchar(10) DEFAULT NULL COMMENT '房间号',
`MERCHANT_ID` int(11) DEFAULT NULL COMMENT '商家ID',
`SERVICE_TYPE` varchar(50) DEFAULT NULL COMMENT '服务类型(与字典表AISW_MERCHANT_DICT表关联)',
`USER_ID` int(11) DEFAULT NULL COMMENT '用户ID(与AISW_USER表关联)',
`FAULT_TYPE` text COMMENT '保修物品(与AISW_MERCHANT_DICT表关联),多个以逗号隔开',
`ACCEPT_STATUS` tinyint(1) DEFAULT '0' COMMENT '受理状态(0-未受理 1-已受理)',
`STATUS` tinyint(1) DEFAULT '1' COMMENT '状态(0-无效 1-有效)',
`CREATE_DATE` datetime DEFAULT NULL COMMENT '创建时间',
`UPDATE_DATE` datetime DEFAULT NULL COMMENT '更新时间',
`CREATE_BY` varchar(50) DEFAULT NULL COMMENT '创建人',
`UPDATE_BY` varchar(50) DEFAULT NULL COMMENT '更新人',
`REMARKS` text COMMENT '备注',
PRIMARY KEY (`ID`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='电竞酒店故障保修服务通知表'; -- aisw_e_service_invoice_msg
CREATE TABLE `aisw_e_service_invoice_msg` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`ROOM_NO` varchar(10) DEFAULT NULL COMMENT '房间号',
`MERCHANT_ID` int(11) DEFAULT NULL COMMENT '商家ID',
`SERVICE_TYPE` varchar(50) DEFAULT NULL COMMENT '服务类型(与字典表AISW_MERCHANT_DICT表关联)',
`USER_ID` int(11) DEFAULT NULL COMMENT '用户ID(与AISW_USER表关联)',
`INVOICE_TYPE` tinyint(1) DEFAULT NULL COMMENT '发票类型(1-单位 2-个人)',
`INVOICE_TITLE` varchar(100) DEFAULT NULL COMMENT '发票抬头',
`INVOICE_TAX_NUMBER` varchar(50) DEFAULT NULL COMMENT '发票税号',
`INVOICE_COMPANY_ADDRESS` varchar(100) DEFAULT NULL COMMENT '单位地址',
`INVOICE_TELEPHONE` varchar(11) DEFAULT NULL COMMENT '电话号码',
`INVOICE_BANK_ACCOUNT` varchar(50) DEFAULT NULL COMMENT '开户银行账户',
`INVOICE_BANK_NAME` varchar(50) DEFAULT NULL COMMENT '开户银行名称',
`ACCEPT_STATUS` tinyint(1) DEFAULT '0' COMMENT '受理状态(0-未受理 1-已受理)',
`STATUS` tinyint(1) DEFAULT '1' COMMENT '状态( 0-无效 1-有效)',
`CREATE_DATE` datetime DEFAULT NULL COMMENT '创建时间',
`UPDATE_DATE` datetime DEFAULT NULL COMMENT '更新时间',
`CREATE_BY` varchar(50) DEFAULT NULL COMMENT '创建人',
`UPDATE_BY` varchar(50) DEFAULT NULL COMMENT '更新人',
`REMARKS` text COMMENT '备注',
PRIMARY KEY (`ID`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='电竞酒店发票服务通知表'; -- aisw_e_service_one_checkout_msg
CREATE TABLE `aisw_e_service_one_checkout_msg` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`ROOM_NO` varchar(10) DEFAULT NULL COMMENT '房间号',
`MERCHANT_ID` int(11) DEFAULT NULL COMMENT '商家ID',
`SERVICE_TYPE` varchar(50) DEFAULT NULL COMMENT '服务类型(与字典表AISW_MERCHANT_DICT表关联)',
`USER_ID` int(11) DEFAULT NULL COMMENT '用户ID(与AISW_USER表关联)',
`ACCEPT_STATUS` tinyint(1) DEFAULT '0' COMMENT '受理状态(0-未受理 1-已受理)',
`STATUS` tinyint(1) DEFAULT '1' COMMENT '状态(0-无效 1-有效)',
`CREATE_DATE` datetime DEFAULT NULL COMMENT '创建时间',
`UPDATE_DATE` datetime DEFAULT NULL COMMENT '更新时间',
`CREATE_BY` varchar(50) DEFAULT NULL COMMENT '创建人',
`UPDATE_BY` varchar(50) DEFAULT NULL COMMENT '更新人',
`REMARKS` text COMMENT '备注',
PRIMARY KEY (`ID`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='电竞酒店一键退房服务通知表'; -- aisw_e_service_wake_msg
CREATE TABLE `aisw_e_service_wake_msg` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`MERCHANT_ID` int(11) DEFAULT NULL COMMENT '商家ID',
`ROOM_NO` varchar(10) DEFAULT NULL COMMENT '房间号',
`SERVICE_TYPE` varchar(50) DEFAULT NULL COMMENT '服务类型(与字典表AISW_MERCHANT_DICT表关联)',
`USER_ID` int(11) DEFAULT NULL COMMENT '用户ID(与AISW_USER表关联)',
`WAKE_DATE` varchar(50) DEFAULT NULL COMMENT '叫醒时间',
`WAKE_PHONE` int(11) DEFAULT NULL COMMENT '叫醒手机号',
`IS_KNOCK` tinyint(1) DEFAULT NULL COMMENT '是否敲门叫醒(0-否 1-是)',
`ACCEPT_STATUS` tinyint(1) DEFAULT '0' COMMENT '受理状态(0-未受理 1-已受理)',
`STATUS` tinyint(1) DEFAULT '1' COMMENT '状态(0-无效 1-有效)',
`CREATE_DATE` datetime DEFAULT NULL COMMENT '创建时间',
`UPDATE_DATE` datetime DEFAULT NULL COMMENT '更新时间',
`CREATE_BY` varchar(50) DEFAULT NULL COMMENT '创建人',
`UPDATE_BY` varchar(50) DEFAULT NULL COMMENT '更新人',
`REMARKS` text COMMENT '备注',
PRIMARY KEY (`ID`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='电竞酒店叫醒服务通知表';
那我写后台就需要对应的写7个接口 和下面这些文件
Controller -> ServiceInterface -> ServiceImpl -> DaoMapper -> MapperXML
组长想了一个策略模式的办法:
只需要一个Controller 和 一个策略接口,但是后面的服务还是需要各自实现
首先看组长写的策略接口:
该接口只定义规范,7个资源共同遵守这个规范来获取资源
package cn.ymcd.aisw.common.strategy; import cn.ymcd.aisw.common.strategy.dto.RoomDTO;
import com.baomidou.mybatisplus.core.metadata.IPage; import java.util.List; /**
* 策略接口
*
* @author wangkun
* @version 1.0
* @projectName aisw-api
* @date 2022年3月16日 11:27
*/
public interface Strategy { /**
* 新增服务
*
* @param jsonParam 服务消息新增传入参数
* @return
* @author wangkun
* @createTime 2020/9/18 11:28
*/
boolean doServiceDataAdd(String jsonParam); /**
* 查询服务翻页
* @param jsonParam
* @return com.baomidou.mybatisplus.core.metadata.IPage<java.lang.Object>
* @author cloud9
* @createTime 2022/3/17 14:29
*
*/
IPage<? extends Object> doServiceDataPage(String jsonParam); /**
* 消息受理更新
* @param jsonParam
* @return boolean
* @author cloud9
* @createTime 2022/3/23 19:18
*
*/
boolean doServiceDataUpdate(String jsonParam);
}
然后组长对7个服务进行了枚举,绑定好实现类的名称
只有Key 和 Value
package cn.ymcd.aisw.common.strategy; /**
* 策略枚举
*
* @author wangkun
* @version 1.0
* @projectName aisw-api
* @date 2022年3月16日 11:27
*/
public enum StrategyEnum { OPERATE_MERCHANT_SERVICE_CONNECT_IMPL("eServiceConnectService", "连接wifi服务实现类"),
OPERATE_MERCHANT_SERVICE_CLEAN_IMPL("eServiceCleanMsgService", "清洁服务实现类"),
OPERATE_MERCHANT_SERVICE_DELIVERY_IMPL("eServiceDeliveryMsgService", "商品配送服务实现类"),
OPERATE_MERCHANT_SERVICE_FAULT_IMPL("eServiceFaultService", "故障保修服务实现类"),
OPERATE_MERCHANT_SERVICE_INVOICE_IMPL("eServiceInvoiceService", "发票服务实现类"),
OPERATE_MERCHANT_SERVICE_RENEWAL_IMPL("eServiceRenewalService", "续住服务实现类"),
OPERATE_MERCHANT_SERVICE_WAKE_IMPL("eServiceWakeService", "唤醒服务实现类"),
OPERATE_MERCHANT_SERVICE_ONE_CHECKOUT_IMPL("eServiceOneCheckoutService", "一键退房服务实现类"),
TEST_IMPL("testServiceImpl", "测试实现类别名"),
; private String value;
private String msg; StrategyEnum(String value,
String msg) {
this.value = value;
this.msg = msg;
} public String getValue() {
return value;
} public String getMsg() {
return msg;
}
}
然后是一个策略装饰器?这个类叫StrategyFacade
最核心的调用在这里实现:
1、内部成员声明一个策略接口的Map容器
2、只存在一个这样的带参构造器,且该参数注解了自动装配?
所有业务实现类注解@Service会存在Bean实例,这个注解的意思像是会把业务Bean都装进来
Key 就是 业务Bean的名字 Value就是Bean的实例
3、获取策略类型,根据提供的channelCode,返回对应的Bean名字
再经过Map容器获取就能得到对应的Bean实例,再调用对应的业务实现类的方法
4、考虑翻页返回的是各个自己的业务PO,所以泛型规约成通用的Object,更新一类的操作则完全可以使用Boolean统一
package cn.ymcd.aisw.common.strategy; import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; /**
* create by wangkun
* Date 2018/06/25
*/
@Service
public class StrategyFacade { private final Map<String, Strategy> strategyMap = new ConcurrentHashMap<>(); /**
* 注入所有实现了Strategy接口的Bean
*
* @param strategyMap
*/
@Autowired
public StrategyFacade(Map<String, Strategy> strategyMap) {
this.strategyMap.clear();
strategyMap.forEach((k, v) -> this.strategyMap.put(k, v));
} /**
* 添加服务信息策略
*
* @param channelCode 渠道code clean-清洁服务 delivery-商品配送服务 fault-故障保修服务 invoice-发票服务 renewal-续住服务 wake-唤醒服务 onecheckout-一键退房
* @param jsonParam 服务消息传入参数
* @return
* @author wangkun
* @createTime 2020/9/18 13:58
*/
public boolean doServiceDataAdd(String channelCode, String jsonParam) {
return strategyMap.get(getStrategyType(channelCode)).doServiceDataAdd(jsonParam);
} /**
* 查询服务信息策略
*
* @param channelCode 渠道code clean-清洁服务 delivery-商品配送服务 fault-故障保修服务 invoice-发票服务 renewal-续住服务 wake-唤醒服务 onecheckout-一键退房
* @param jsonParam 服务消息传入参数
* @return
* @author wangkun
* @createTime 2020/9/18 13:58
*/
public IPage<? extends Object> doServiceDataPage(String channelCode, String jsonParam) {
return strategyMap.get(getStrategyType(channelCode)).doServiceDataPage(jsonParam);
} /***
* 消息受理更新
* @param channelCode
* @param jsonParam
* @return boolean
* @author 戴知舟
* @createTime 2022/3/23 19:17
*
*/
public boolean doServiceDataUpdate(String channelCode, String jsonParam) {
return strategyMap.get(getStrategyType(channelCode)).doServiceDataUpdate(jsonParam);
} /**
* 根据不同条件生成不同的策略(使用策略场景变化是需要修改)
*
* @param channelCode 渠道code
* @return
* @author wangkun
* @createTime 2020/9/18 14:00
*/
private static String getStrategyType(String channelCode) {
switch (channelCode) {
case "connect":
//连接WIFI服务信息处理
return StrategyEnum.OPERATE_MERCHANT_SERVICE_CONNECT_IMPL.getValue();
case "clean":
//清洁服务信息处理
return StrategyEnum.OPERATE_MERCHANT_SERVICE_CLEAN_IMPL.getValue();
case "delivery":
//商品配送服务信息处理
return StrategyEnum.OPERATE_MERCHANT_SERVICE_DELIVERY_IMPL.getValue();
case "fault":
//故障保修服务信息处理
return StrategyEnum.OPERATE_MERCHANT_SERVICE_FAULT_IMPL.getValue();
case "invoice":
//发票服务信息处理
return StrategyEnum.OPERATE_MERCHANT_SERVICE_INVOICE_IMPL.getValue();
case "renewal":
//续住服务信息处理
return StrategyEnum.OPERATE_MERCHANT_SERVICE_RENEWAL_IMPL.getValue();
case "wake":
//唤醒服务信息处理
return StrategyEnum.OPERATE_MERCHANT_SERVICE_WAKE_IMPL.getValue();
case "oneCheckout":
//一键退房服务信息处理
return StrategyEnum.OPERATE_MERCHANT_SERVICE_ONE_CHECKOUT_IMPL.getValue();
default:
//测试类
return StrategyEnum.TEST_IMPL.getValue();
}
} }
在Controller中的调用是这样的:
根据约定好的channelCode来完成不同业务的调用
package cn.ymcd.aisw.room.controller; import cn.ymcd.aisw.common.Constant;
import cn.ymcd.aisw.common.strategy.StrategyFacade;
import cn.ymcd.aisw.common.strategy.dao.EServiceBasicDAO;
import cn.ymcd.aisw.room.dto.EServiceMsgDTO;
import cn.ymcd.comm.base.BaseController;
import cn.ymcd.wss.util.json.JacksonUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.http.util.Asserts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import java.util.List;
import java.util.Map; /**
* aisw_e_service_msg 电竞酒店服务通知表 前端控制器
*
* @projectName:
* @author:daizhizhou
* @date:2022-03-14
* @version 1.0
*/
@Api(tags = "客房服务 - 服务申请")
@RestController
@RequestMapping("${sys.path}/room/message")
public class EServiceMsgController extends BaseController { @Autowired
private StrategyFacade strategyFacade; @Autowired
private EServiceBasicDAO eServiceBasicDAO; /**
* /sys/room/message/page
* @param json
* @return com.baomidou.mybatisplus.core.metadata.IPage<cn.ymcd.aisw.room.dto.EServiceMsgDTO>
* @author cloud9
* @createTime 2022/3/17 15:09
* {
* "channelCode":"wake",
* "jsonParam":{
* "merchantId":"1001",
* "serviceType":"360000002",
* "unionId":"o9K950jpDrqIRiR_4pNqT89RgEhs",
* "cleanDate":"12:00",
* "page": {
* "size": 10,
* "current: 1
* }
* }
*/
@ApiOperation(value = "消息通知查询", notes = "消息通知查询")
@PostMapping("/page")
public IPage<Object> doServiceDataPage(@RequestBody String json) {
Asserts.notEmpty(json, "传入参数为空");
Map<String, Object> map = JacksonUtil.jsonToMap(json);
String channelCode = map.get("channelCode").toString();
String jsonParam = map.get("jsonParam").toString();
return (IPage<Object>)strategyFacade.doServiceDataPage(channelCode, jsonParam);
}
}
其中的一个策略实现类,就是业务实现类:
注意@Service注解的名称,通过这个Bean名称决定Spring是否装配进Map容器
package cn.ymcd.aisw.common.strategy.impl; import cn.ymcd.aisw.common.CommonExtendUtils;
import cn.ymcd.aisw.common.strategy.Strategy;
import cn.ymcd.aisw.common.strategy.dao.EServiceBasicDAO;
import cn.ymcd.aisw.common.strategy.dao.EServiceCleanMsgDAO;
import cn.ymcd.aisw.common.strategy.dao.UserDAO;
import cn.ymcd.aisw.common.strategy.dto.EServiceCleanMsgDTO;
import cn.ymcd.aisw.common.strategy.dto.UserDTO;
import cn.ymcd.wss.util.json.JacksonUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.stereotype.Service; import javax.annotation.Resource; /**
* 清洁服务策略
*
* @author wangkun
* @version 1.0
* @projectName aisw-api
* @date 2022年03月16日 10:47
*/
@Service("eServiceCleanMsgService")
public class EServiceCleanMsgServiceImpl implements Strategy { @Resource
private EServiceCleanMsgDAO eServiceCleanMsgDAO; @Resource
private UserDAO userDAO; @Resource
private EServiceBasicDAO eServiceBasicDAO;
/**
*
* @param jsonParam
* @return com.baomidou.mybatisplus.core.metadata.IPage<cn.ymcd.aisw.common.strategy.dto.EServiceCleanMsgDTO>
* @author cloud9
* @createTime 2022/3/17 15:01
*
* {
* "channelCode":"clean",
* "jsonParam":{
* "merchantId":"1001",
* "serviceType":"360000002",
* "unionId":"o9K950jpDrqIRiR_4pNqT89RgEhs",
* "cleanDate":"12:00",
* "page": {
* "size": 10,
* "current: 1
* }
* }
* }
*
*/
@Override
public IPage<EServiceCleanMsgDTO> doServiceDataPage(String jsonParam) {
EServiceCleanMsgDTO cleanMsgDTO = JacksonUtil.jsonToObject(jsonParam, EServiceCleanMsgDTO.class); // cleanMsgDTO.setMerchantId(merchantBasicDAO.getMerchantIdBySysUserId(LoginUserContext.getUser().getId()));
cleanMsgDTO.setMerchantId(eServiceBasicDAO.getMerchantIdBySysUserId("user1001"));
return eServiceCleanMsgDAO.cleanServiceMsgPage(cleanMsgDTO.getPage(), cleanMsgDTO);
}
}
最后是接口测试

里面存在的一些问题:
有些业务操作是在小程序端的
小程序不需要翻页和消息查询,只是提供给酒店用户这些服务功能
但是这个业务所在的实现类必须也要按照策略接口实现方法,实现,但是不需要这个资源
有那么一点点资源浪费
【Java】项目采用的设计模式案例的更多相关文章
- Java虚拟机类加载机制——案例分析
转载: Java虚拟机类加载机制--案例分析 在<Java虚拟机类加载机制>一文中详细阐述了类加载的过程,并举了几个例子进行了简要分析,在文章的最后留了一个悬念给各位,这里来揭开这个悬 ...
- Java学生管理系统项目案例
这是一个不错的Java学生管理系统项目案例,希望能够帮到大家的学习吧. 分代码如下 package com.student.util; import java.sql.Connection; impo ...
- Java中单态设计模式
Java中单态设计模式 2011-09-23 16:38:46| 分类: Java | 标签:technology! |举报|字号 订阅 此博文是转自新浪博客中一名叫做"俊俊的 ...
- Java多态面试题案例几解题思路
---恢复内容开始--- Java多态面试题案例几解题思路 这道题是来自别人,先开始看到题很懵,后来有自己的思路: class A { public String show(D obj){ retur ...
- java基础-多线程应用案例展示
java基础-多线程应用案例展示 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.两只熊,100只蜜蜂,蜜蜂每次生产的蜂蜜量是1,罐子的容量是30,熊在罐子的蜂蜜量达到20的时候 ...
- Java基础-数据类型应用案例展示
Java基础-数据类型应用案例展示 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.把long数据转换成字节数组,把字节数组数据转换成long. /* @author :yinz ...
- 【转】java io 流 设计模式
知识点:什么是装饰模式: http://wenku.baidu.com/view/ad4eac9f51e79b896802263b.html(原理讲的很清楚) http://wenku.baidu.c ...
- java 23种设计模式,一般情况下,常用的有哪些? 转载
原址:http://wangle.iteye.com/blog/196972 工厂模式, 工厂方法模式,单例模式, 外观(Facade)模式, 观察者(Observer)模式,桥接(Bridge)模式 ...
- JDK/Java里的设计模式
JDK/Java里的设计模式
- JAVA WEB项目开发案例精粹
http://www.blogjava.net/zongbao/archive/2012/07/24/383884.htmlJAVA WEB项目开发案例精粹.pdf main Alt + / => ...
随机推荐
- 为何Mysql数据库上读和代码读取的数据不一致
上周,做了一个同步删除的功能,具体流程是,数据库删除-->调用第三方运行删除接口,同步删除. 具体流程 数据库删除数据后,这里使用标志删除,再调用第三方数据. 在调用第三方数据之前需要通过id查 ...
- mac os 10.15.1 懒人 .CDR
链接:https://pan.baidu.com/s/1MHbUnHWQuGVE1P36mTjmkQ 提取码:ohlu
- flutter 结合 springBoot 完成登录 注册 功能
后端接口 前端调用接口代码 import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import '../page ...
- Kubernetes(二)资源管理
1. 资源管理介绍 在kubernetes中,所有内容都抽象为资源,用户需要操作资源来管理kubernetes. Kubernetes本质上就是一个集群系统,用户可以在集群中部署各种服务,所谓的部署服 ...
- 集成学习与随机森林(二)Bagging与Pasting
Bagging 与Pasting 我们之前提到过,其中一个获取一组不同分类器的方法是使用完全不同的训练算法.另一个方法是为每个预测器使用同样的训练算法,但是在训练集的不同的随机子集上进行训练.在数据抽 ...
- 【动画进阶】类 ChatGpt 多行文本打字效果
今天我们来学习一个有意思的多行文本输入打字效果,像是这样: 这个效果其实本身并非特别困难,实现的方式也很多,在本文中,我们更多的会聚焦于整个多行打字效果最后的动态光标的实现. 也就是如何在文本不断变长 ...
- C语言自动编译执行脚本
C语言自动编译执行脚本 在Linux上面用命令行写一些简单的C语言程序,总是遇到一个问题,代码写完后要先编译后运行,而且编译生成的可执行文件默认还是a.out,自己去加参数去改有觉得十分麻烦,所以干脆 ...
- 基于RK3588的NPU案例分享!6T是真的强!
RK3588 NPU简介 作为瑞芯微新一代旗舰工业处理器,RK3588 NPU性能可谓十分强大,6TOPS设计能够实现高效的神经网络推理计算.这使得RK3588在图像识别.语音识别.自然语言处理等人工 ...
- 国芯新作 | 四核Cortex-A53@1.4GHz,仅168元起?含税?哇!!!
获取更多T507全国产平台资料可在评论区留言或关注官方公众号~
- 复习 - ajax
复习呢有一个很直观的感受,就是以前学的东西,萌懂半懂的,这一来全部都清楚了,你以前以为你学的并不好但是复习一次把以前的案例一做,居然能够自己独立完成,知识点看着掌握的还不错. 1. 两天时间就把整个a ...