美文网首页程序员
spring-boot下如何满足多生产环境中个性化定制功能

spring-boot下如何满足多生产环境中个性化定制功能

作者: java云帆 | 来源:发表于2019-03-28 22:50 被阅读0次

在项目的开发中,我们很难做到开发一套标准的流程来解决所有客户的需求。比如,我们当前的计量项目,分别运行于赤峰市和河北省。虽然两个区域处理的业务相同,但是对细节的实现要求却不同。前面也学习过计量检定软件,其为了解决各个定制者使用的功能需求,最后采取的方案是:将基础项目复制多份,进而满足不同的客户需求。优点当然是有的,但比起缺点来,优点便不值一提。缺点很明显,总结为一句话就是:项目变得难以维护。所以,当前让我们看到的就是,几个开发人员,每天处于解决问题当中。本文将给出一种方案,来有效的规避上述问题。

资源与环境

开发环境:java1.8 + spring-boot:2.1.3.RELEASE

需求假设

假设使用本项目的人员为:中国人、美国人,分别能接受的语言为中文和英文。

项目运行后,可以根据当前的访问人员是国籍来动态显示: 你好 或 hello

有新的需求后,比如:增加德国人并显示 Hallo 。增加功能时,不更改核心代码。

不使用if else

注意:如果你看完需求假设后,毫无触动,请忽略本文以下内容

解决方案

解决方案中,我们涉及了两种设计模块,分别为: 策略模式 及 工厂模式 。

策略模式:一般用于将具体的 算法 进行抽象及剥离。此项目中,我们的具体算法是 说你好 。

工厂模式:一般用于根据环境来动态的创建BEAN的情况下。引项目中,我们将根据不同国家的人,来返回不同的 说你好 这个算法。

先给出UML图:

SpeakService

SpeakService 即为我们供其它模块调用的 说话服务 ,调用其中的 SayHello() 来完成 说你好功能。

package com.mengyunzhi.demo.dynamicautowire;

/**

* 你好

*/

public interface SpeakService {

void sayHello();

}

在其实现类中,我们注入 SayHelloFactory ,让其来返回正确的 SayHelloService ,最终调用 sayHello() 来完成目标。

package com.mengyunzhi.demo.dynamicautowire;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

/**

* 你好

*/

@Service

public class SpeakServiceImpl implements SpeakService {

private final

SayHelloFactory sayHelloFactory; // 说话工厂

@Autowired

public SpeakServiceImpl(SayHelloFactory sayHelloFactory) {

this.sayHelloFactory = sayHelloFactory;

}

@Override

public void sayHello() {

this.sayHelloFactory.getSayHelloService().sayHello();

}

}

SayHelloFactory

package com.mengyunzhi.demo.dynamicautowire;

/**

* 说话工厂

*/

public interface SayHelloFactory {

void setCountryCode(CountryCode countryCode);

SayHelloService getSayHelloService();

}

在此,我们增加一个 CountryCode 表示当前访问者的国家。其实在获取访问者国家时,我们也可以调用其它Bean的其它来实现。

package com.mengyunzhi.demo.dynamicautowire;

/**

* 国家代码

*/

public enum CountryCode {

CHINA((byte) 0, "中国"),

USA((byte) 1, "美国");

private Byte code;

private String name;

CountryCode(Byte code, String name) {

this.code = code;

this.name = name;

}

public Byte getCode() {

return code;

}

public String getName() {

return name;

}

}

使用 enum 来控制范围,避免 Factory 在获取Bean时发生异常。

package com.mengyunzhi.demo.dynamicautowire;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

/**

* 说话工厂

*/

@Service

public class SayHelloFactoryImpl implements SayHelloFactory {

/**

* BEAN列表

*/

private final Map servicesByCode = new HashMap<>();

/**

* 国家代码

*/

private CountryCode countryCode = CountryCode.CHINA;

@Override

public void setCountryCode(CountryCode countryCode) {

this.countryCode = countryCode;

}

/**

* 初始化

*

* @param sayHelloServices spring获取到的所以实现了SpeakService的BEAN

*/

@Autowired

public void init(List sayHelloServices) {

for (SayHelloService sayHelloService : sayHelloServices) {

this.register(sayHelloService.getCode(), sayHelloService);

}

}

/**

* 注册Bean

*

* @param code 代码

* @param sayHelloService BEAN

*/

private void register(Byte code, SayHelloService sayHelloService) {

this.servicesByCode.put(code, sayHelloService);

}

/**

* 获取BEAN

*

* @return 对应的SayHelloService BEAN

*/

@Override

public SayHelloService getSayHelloService() {

return this.servicesByCode.get(this.countryCode.getCode());

}

}

增加 Map<Byte, SayHelloService> servicesByCode 来存储对应国家的 SayHelloService BEAN。增加 getSayHelloService() 来根据当前国家代码来返回相应的Bean。

SayHelloService

package com.mengyunzhi.demo.dynamicautowire;

/**

* 说话

*/

public interface SayHelloService {

void sayHello();

Byte getCode();

}

将 sayHello() 方法抽离, getCode() 以获取国家代码。

中国人你好

package com.mengyunzhi.demo.dynamicautowire;

import org.springframework.stereotype.Component;

/**

* 中国话

*/

@Component

public class SayHelloServiceChineseImpl implements SayHelloService {

@Override

public void sayHello() {

System.out.println("您好");

}

@Override

public Byte getCode() {

return CountryCode.CHINA.getCode();

}

}

美国人Hello

package com.mengyunzhi.demo.dynamicautowire;

import org.springframework.stereotype.Component;

/**

* 美国话

*/

@Component

public class SayHelloServiceEnglishImpl implements SayHelloService {

@Override

public void sayHello() {

System.out.println("hello");

}

@Override

public Byte getCode() {

return CountryCode.USA.getCode();

}

}

测试

package com.mengyunzhi.demo.dynamicautowire;

import org.junit.Test;

import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.test.context.SpringBootTest;

import org.springframework.test.context.junit4.SpringRunner;

@SpringBootTest

@RunWith(SpringRunner.class)

public class SpeakServiceImplTest {

@Autowired

SpeakService speakService;

@Autowired

SayHelloFactory sayHelloFactory;

@Test

public void sayHello() {

// 默认说你好

speakService.sayHello();

// 将国家设置为美国,再说你好

sayHelloFactory.setCountryCode(CountryCode.USA);

speakService.sayHello();

// 将国家设置为中国,再说你好

sayHelloFactory.setCountryCode(CountryCode.CHINA);

speakService.sayHello();

}

}

您好

hello

您好

时序图

增加德国人

SayHelloServiceGermanyImpl

CountryCode

package com.mengyunzhi.demo.dynamicautowire;

import org.springframework.stereotype.Component;

@Component

public class SayHelloServiceGermanyImpl implements SayHelloService {

@Override

public void sayHello() {

System.out.println("Hallo");

}

@Override

public Byte getCode() {

return CountryCode.GERMANY.getCode();

}

}

package com.mengyunzhi.demo.dynamicautowire;

/**

* 国家代码

*/

public enum CountryCode {

CHINA((byte) 0, "中国"),

USA((byte) 1, "美国"),

GERMANY((byte) 2, "德国");

private Byte code;

private String name;

CountryCode(Byte code, String name) {

this.code = code;

this.name = name;

}

public Byte getCode() {

return code;

}

public String getName() {

return name;

}

}

单元测试

@Test

public void sayHello1() {

// 默认说你好

speakService.sayHello();

// 将国家设置为美国,再说你好

sayHelloFactory.setCountryCode(CountryCode.USA);

speakService.sayHello();

// 将国家设置为德国,再说你好

sayHelloFactory.setCountryCode(CountryCode.GERMANY);

speakService.sayHello();

// 将国家设置为中国,再说你好

sayHelloFactory.setCountryCode(CountryCode.CHINA);

speakService.sayHello();

}

测试结果如下:

您好

hello

Hallo

您好

总结

在解决问题时,只所有我们看的不够远,可能是由于自己站的不够高。同样的问题,困惑我了多日,直到近期系统的学习 设计模式 、 angular官方教程 、 Spring 实战 后,结合近期项目变更带来的新需求,才在使用设计模式解决此问题上有所启发。

最后,给大家推荐一个**Java进阶内推交流群730379855**,不管你在地球哪个方位,不管你参加工作几年都欢迎你的入驻!(群内会免费提供一些群主收藏的免费学习书籍资料以及整理好的几百道面试题和答案文档!)

相关文章

  • spring-boot下如何满足多生产环境中个性化定制功能

    在项目的开发中,我们很难做到开发一套标准的流程来解决所有客户的需求。比如,我们当前的计量项目,分别运行于赤峰市和河...

  • 有关工业4.0

    网上看到这个总结比较好,整理一下。 工业4.0之智能生产 从个性化订单起,多品种、小批量、定制生产。 工业4.0之...

  • 铝企业生产调度优化研究与应用

    在复杂多变的市场环境下,如何满足多品种、小批量和客户个性化的需求,如何合理配置和有效利用企业关键资源,如何通过信息...

  • 德振科技

    数字经济新模式 集中起来有四大模式:一是个性化定制,满足消费者新的需求;二是智能化生产,适应于大规模定制生产方...

  • 你都不知道?个性化定制要这么做才“好玩”!

    大规模个性化定制的需求日益迫切。在手工业时代,个性化定制是最流行的生产方式,后来随着工业标准化大生产的实现,忠实于...

  • 吉林市最新卧室定制衣柜书柜组合效果图

    目前,定制衣柜不仅仅能满足顾客个性化的需求,还能延伸出做书柜的功能,下面装乐购为大家介绍几款最新卧室定制衣柜书...

  • 讲究的生活方式,定制化厨房设计

    消费升级,品味升级,审美升级,大家对于个性化定制越来推崇,目前的设计已经不能满足大家对于个性化的需求! 所以定制系...

  • 爱比尔家居定制衣柜多少钱一米

    定制衣柜虽然是这几年流行起来,由于它的个性化以及多功能,能满足消费者的需求,不少朋友在购买衣柜大多数都选择衣柜定制...

  • postman的环境

    如何在postman中创建环境: 创建多套环境 环境可以有多套:开发,测试,生产 使用指定环境 在左上角选择对应的...

  • 2017-09-08

    如何改变企业千篇一律的体检套餐模式 满足员工个性化定制 如何解决用户多次跑医院预约项目问题 满足员工一次性预约 如...

网友评论

    本文标题:spring-boot下如何满足多生产环境中个性化定制功能

    本文链接:https://www.haomeiwen.com/subject/hfehbqtx.html