精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

DDD 領域驅動決策規則樹服務架構設計

開發 架構
一些大型架構設計往往不是換一個設計模型就能徹底提升效率,還是需要人員整體素質,這是一個不斷培養的過程。領域驅動設計的思想并不只是教會程序猿寫代碼,也是非程序員以外的所有互聯網人員都適合學習的內容。

前言介紹

在上一章節介紹了領域驅動設計的基本概念以及按照領域驅動設計的思想進行代碼分層,但是僅僅只是從一個簡單的分層結構上依然沒法理解DDD以及如何去開發這樣的微服務。另外往往按照這樣分層后依然感覺和MVC也沒有什么差別,也沒有感受到帶來什么非常大的好處。那么問題出在哪呢?我個人覺得DDD學起來更像是一套指導思想,不斷的將學習者引入到領域觸發的思維中去,而這恰恰也是最難學習的地方。時而感覺會了,而實際開發中又不對,本來已經拆解清晰了,但怎么又那么像MVC了。甚至懷疑自己,我在干嘛?

無論是DDD、MVC,他們更像是家里三居或者四局的格局,每一種格局方式都是為了更好的實現對應架構下的設計思想。但,不是說給你一個通用的架構模式,你就能開發出干凈(高內聚)、整潔(低耦合)、漂亮(模塊化)的代碼。這就像是你家住三居、他家也住三居,但是你們屋子的舒適情況就一樣嗎?{再有,你家里會把廁所安在廚房嗎?但你的代碼是否這么干過,不合理的擺放導致重構延期。}

另外DDD之所以看著簡單但又不那么好落地,個人認為很重要就是領域思想,DDD只是指導但是不能把互聯網天下每一個業務行為開發都拿出來舉例子給你看,每個領域需要設計。所以需要一些領域專家{產品+架構+不是杠精的程序猿}來討論梳理,將業務形態設計出合理的架構&代碼。

案例目標

本案例通過一個商品下單規則的場景來進行演示DDD;

  1. 假設產品需求業務運行人員可以對不同的商品配置一些規則,這些規則可以滿足不同用戶類型可以下單不同商品。
  2. 另外一些行為規則是會隨著業務發展而增加或者變動的,所以不能寫死{寫死太嚇人了}。
  3. 數據庫的PO類不應該被外部服務調用,這也是必須的。如果你開發過很多系統,那么可能已經吃過虧并意識到這個問題。
  4. 按照DDD思想我們嘗試需要設計一個規則引擎的服務,通過給外部提供非常簡單的接口(application)來獲取最終結果。
  5. 通過這樣的案例可以很容易的感受到目前的四層架構確實在實現DDD思想上有很多的幫助。

如圖;DDD分層結構 | 指導設計架構

bugstack蟲洞棧 & 分層結構

DDD思想 · 開發設計

通過領域驅動設計的思想,從領域知識中提取和劃分為一個一個的子領域(核心子域,通用子域,支撐子域),并在子領域上建立模型。那么在技術實現上就需要去支撐這種建模,以使我們的代碼模塊獨立、免污染、易于擴展。

在上面我們提到需要開發一個可擴展使用的規則樹,那么如果只是單純的一次性需求,最快的方式是if語句就搞定了。但是為了使這個領域服務具備良好的使用和擴展性,我們需要做些拆分,那么如下;

  1. 你是否想過系統在過濾過則的時候其實就像執行一棵二叉樹一樣非左即右側,每一條線上都有著執行條件,通過判斷來達到最終的結果。
  2. 按照樹形結構我們將定義出來四個類;樹、節點、果實、指向線(From-To),用于描述我們的規則行為。
  3. 再此基礎上需要實現一個邏輯定義與規則樹執行引擎,通過統一的引擎服務來執行我們每次配置好的規則樹。

如圖;領域開發設計服務

bugstack蟲洞棧 & 領域開發設計服務

工程模型

itstack-demo-ddd-02
└── src
├── main
│ ├── java
│ │ └── org.itstack.demo
│ │ ├── application
│ │ │ ├── MallRuleService.java
│ │ │ └── MallTreeService.java
│ │ ├── domain
│ │ │ ├── rule
│ │ │ │ ├── model
│ │ │ │ │ ├── aggregates
│ │ │ │ │ │ └── UserRichInfo.java
│ │ │ │ │ └── vo
│ │ │ │ │ ├── DecisionMatter.java
│ │ │ │ │ ├── EngineResult.java
│ │ │ │ │ ├── TreeNodeInfo.java
│ │ │ │ │ ├── TreeNodeLineInfo.java
│ │ │ │ │ └── UserSchool.java
│ │ │ │ ├── repository
│ │ │ │ │ └── IRuleRepository.java
│ │ │ │ └── service
│ │ │ │ ├── engine
│ │ │ │ │ ├── impl
│ │ │ │ │ └── EngineFilter.java
│ │ │ │ ├── logic
│ │ │ │ │ ├── impl
│ │ │ │ │ └── LogicFilter.java
│ │ │ │ └── MallRuleServiceImpl.java
│ │ │ └── tree
│ │ │ ├── model
│ │ │ │ ├── aggregates
│ │ │ │ │ └── TreeCollect.java
│ │ │ │ └── vo
│ │ │ │ ├── TreeInfo.java
│ │ │ │ └── TreeRulePoint.java
│ │ │ ├── repository
│ │ │ │ └── ITreeRepository.java
│ │ │ └── service
│ │ │ └── MallTreeServiceImpl.java
│ │ ├── infrastructure
│ │ │ ├── common
│ │ │ │ └── Constants.java
│ │ │ ├── dao
│ │ │ │ ├── RuleTreeDao.java
│ │ │ │ ├── RuleTreeNodeDao.java
│ │ │ │ └── RuleTreeNodeLineDao.java
│ │ │ ├── po
│ │ │ │ ├── RuleTree.java
│ │ │ │ ├── RuleTreeConfig.java
│ │ │ │ ├── RuleTreeNode.java
│ │ │ │ └── RuleTreeNodeLine.java
│ │ │ ├── repository
│ │ │ │ ├── cache
│ │ │ │ │ └── RuleCacheRepository.java
│ │ │ │ ├── mysql
│ │ │ │ │ ├── RuleMysqlRepository.java
│ │ │ │ │ └── TreeMysqlRepository.java
│ │ │ │ ├── RuleRepository.java
│ │ │ │ └── TreeRepository.java
│ │ │ └── util
│ │ │ └── CacheUtil.java
│ │ ├── interfaces
│ │ │ ├── dto
│ │ │ │ ├── DecisionMatterDTO.java
│ │ │ │ └── TreeDTO.java
│ │ │ └── DDDController.java
│ │ └── DDDApplication.java
│ └── resources
│ ├── mybatis
│ └── application.yml
└── test
└── java
└── org.itstack.demo.test
└── ApiTest.java

application應用層

application/MallRuleService.java | 應用層定義接口服務,也可以適當做簡單包裝

/**
* 商超規則過濾服務;提供規則樹決策功能
* 微信公眾號:bugstack蟲洞棧 | 專注原創技術專題案例
* 論壇:http://bugstack.cn
* Create by 付政委 on @2019
*/
public interface MallRuleService {

/**
* 決策服務
* @param matter 決策物料
* @return
EngineResult process(final DecisionMatter matter);

}

domain領域層

domain中有兩個領域服務;規則樹信息領域、規則執行領域,通過合理的抽象化來實現高內聚、低耦合的模塊化服務

domain/service/MallRuleServiceImpl.java | 領域層中的service來實現應用層接口

/**
* 規則樹服務;提供規則規律功能
*
* 1、rule包下只進行規則決策領域的處理
* 2、封裝決策行為到領域模型中,外部只需要調用和處理結果即可
* 3、可以擴展不同的決策引擎進行統一管理
*
* 微信公眾號:bugstack蟲洞棧 | 專注原創技術專題案例
* 論壇:http://bugstack.cn
* Create by 付政委 on @2019
*/
@Service("mallRuleService")
public class MallRuleServiceImpl implements MallRuleService {

private Logger logger = LoggerFactory.getLogger(MallRuleServiceImpl.class);

@Resource(name = "ruleEngineHandle")
private EngineFilter ruleEngineHandle;

@Override
public EngineResult process(DecisionMatter matter){
try {
return ruleEngineHandle.process(matter);
} catch (Exception e) {
logger.error("決策引擎執行失敗", e);
return new EngineResult(false);
}
}

}

domain/service/logic/LogicFilter.java | 邏輯決策定義

/**
* 微信公眾號:bugstack蟲洞棧 | 專注原創技術專題案例
* 論壇:http://bugstack.cn
* Create by 付政委 on @2019
*/
public interface LogicFilter {

/**
* 邏輯決策器
* @param matterValue 決策值
* @param treeNodeLineInfoList 決策節點
* @return
Long filter(String matterValue, List<TreeNodeLineInfo> treeNodeLineInfoList);

/**
* 獲取決策值
*
* @param decisionMatter 決策物料
* @return
String matterValue(DecisionMatter decisionMatter);

}

domain/service/engine/EngineFilter.java | 引擎執行定義

/**
* 微信公眾號:bugstack蟲洞棧 | 專注原創技術專題案例
* 論壇:http://bugstack.cn
* Create by 付政委 on @2019
*/
public interface EngineFilter {

EngineResult process(final DecisionMatter matter) throws Exception;

}

infrastructure基礎層

1、實現領域層倉儲定義 2、數據庫操作為非業務屬性的功能操作 3、在倉儲實現層進行組合裝配DAO&Redis&Cache等

infrastructure/repository/RuleRepository.java

/**
* 微信公眾號:bugstack蟲洞棧 | 專注原創技術專題案例
* 論壇:http://bugstack.cn
* Create by 付政委 on @2019
*/
public interface EngineFilter {

EngineResult process(final DecisionMatter matter) throws Exception;

}

interfaces接口層

1、包裝應用接口對外提供api 2、外部傳輸對象采用DTO類,主要為了避免內部類被污染{不斷的迭代的需求會在類中增加很多字段} 3、目前依然是提供的Http服務,如果提供的rpc服務,將需要對外提供可引用jar

interfaces/DDDController.java

**
* 微信公眾號:bugstack蟲洞棧 | 歡迎關注學習專題案例
* 論壇:http://bugstack.cn
* Create by 付政委 on @2019
*/
@Controller
public class DDDController {

private Logger logger = LoggerFactory.getLogger(DDDController.class);

@Resource
private MallTreeService mallTreeService;
@Resource
private MallRuleService mallRuleService;

/**
* 測試接口:http://localhost:8080/api/tree/queryTreeSummaryInfo
* 請求參數:{"treeId":10001}
*/
@RequestMapping(path = "/api/tree/queryTreeSummaryInfo", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity queryTreeSummaryInfo(@RequestBody TreeDTO request) {
String reqStr = JSON.toJSONString(request);
try {
logger.info("查詢規則樹信息{}Begin req:{}", request.getTreeId(), reqStr);
TreeCollect treeCollect = mallTreeService.queryTreeSummaryInfo(request.getTreeId());
logger.info("查詢規則樹信息{}End res:{}", request.getTreeId(), JSON.toJSON(treeCollect));
return new ResponseEntity<>(treeCollect, HttpStatus.OK);
} catch (Exception e) {
logger.error("查詢規則樹信息{}Error req:{}", request.getTreeId(), reqStr, e);
return new ResponseEntity<>(e.getMessage(), HttpStatus.OK);
}
}

/**
* 測試接口:http://localhost:8080/api/tree/decisionRuleTree
* 請求參數:{"treeId":10001,"userId":"fuzhengwei","valMap":{"gender":"man","age":"25"}}
*/
@RequestMapping(path = "/api/tree/decisionRuleTree", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity decisionRuleTree(@RequestBody DecisionMatterDTO request) {
String reqStr = JSON.toJSONString(request);
try {
logger.info("規則樹行為信息決策{}Begin req:{}", request.getTreeId(), reqStr);
DecisionMatter decisionMatter = new DecisionMatter();
decisionMatter.setTreeId(request.getTreeId());
decisionMatter.setUserId(request.getUserId());
decisionMatter.setValMap(request.getValMap());
EngineResult engineResult = mallRuleService.process(decisionMatter);
logger.info("規則樹行為信息決策{}End res:{}", request.getTreeId(), JSON.toJSON(engineResult));
return new ResponseEntity<>(engineResult, HttpStatus.OK);
} catch (Exception e) {
logger.error("規則樹行為信息決策{}Error req:{}", request.getTreeId(), reqStr, e);
return new ResponseEntity<>(e.getMessage(), HttpStatus.OK);
}
}

}

測試驗證

規則樹結構{數據庫轉Json} | 可自行定義

{
"treeNodeMap": {
"1": {
"nodeType": 1,
"ruleDesc": "用戶性別[男/女]",
"ruleKey": "userGender",
"treeId": 10001,
"treeNodeId": 1,
"treeNodeLineInfoList": [
{
"nodeIdFrom": 1,
"nodeIdTo": 11,
"ruleLimitType": 1,
"ruleLimitValue": "man"
},
{
"nodeIdFrom": 1,
"nodeIdTo": 12,
"ruleLimitType": 1,
"ruleLimitValue": "woman"
}
]
},
"11": {
"nodeType": 1,
"ruleDesc": "用戶年齡",
"ruleKey": "userAge",
"treeId": 10001,
"treeNodeId": 11,
"treeNodeLineInfoList": [
{
"nodeIdFrom": 11,
"nodeIdTo": 111,
"ruleLimitType": 3,
"ruleLimitValue": "25"
},
{
"nodeIdFrom": 11,
"nodeIdTo": 112,
"ruleLimitType": 3,
"ruleLimitValue": "25"
}
]
},
"12": {
"nodeType": 1,
"ruleDesc": "用戶年齡",
"ruleKey": "userAge",
"treeId": 10001,
"treeNodeId": 12,
"treeNodeLineInfoList": [
{
"nodeIdFrom": 12,
"nodeIdTo": 121,
"ruleLimitType": 3,
"ruleLimitValue": "25"
},
{
"nodeIdFrom": 12,
"nodeIdTo": 122,
"ruleLimitType": 3,
"ruleLimitValue": "25"
}
]
},
"111": {
"nodeType": 2,
"nodeValue": "果實A",
"treeId": 10001,
"treeNodeId": 111,
"treeNodeLineInfoList": [ ]
},
"112": {
"nodeType": 2,
"nodeValue": "果實B",
"treeId": 10001,
"treeNodeId": 112,
"treeNodeLineInfoList": [ ]
},
"121": {
"nodeType": 2,
"nodeValue": "果實C",
"treeId": 10001,
"treeNodeId": 121,
"treeNodeLineInfoList": [ ]
},
"122": {
"nodeType": 2,
"nodeValue": "果實D",
"treeId": 10001,
"treeNodeId": 122,
"treeNodeLineInfoList": [ ]
}
},
"treeRoot": {
"treeId": 10001,
"treeName": "購物分類規則樹",
"treeRootNodeId": 1
}
}

通過postman調用 | raw => json

查詢規則樹信息 測試接口:http://localhost:8080/api/tree/decisionRuleTree 請求參數:{"treeId":10001}

{
"treeInfo": {
"treeId": 10001,
"treeName": "購物分類規則樹",
"treeDesc": "用于分類不同類型用戶可購物范圍",
"nodeCount": 7,
"lineCount": 6
},
"treeRulePointList": [
{
"ruleKey": "userGender",
"ruleDesc": "用戶性別[男/女]"
},
{
"ruleKey": "userAge",
"ruleDesc": "用戶年齡"
}
]
}

微信公眾號:bugstack蟲洞棧 & 查詢規則樹信息

規則樹行為信息決策 測試接口:http://localhost:8080/api/tree/decisionRuleTree 請求參數:{"treeId":10001}

{
"userId": "fuzhengwei",
"treeId": 10001,
"nodeId": 112,
"nodeValue": "果實B",
"success": true
}

微信公眾號:bugstack蟲洞棧 & 規則樹行為信息決策

  .   ____          _            __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.5.RELEASE)

2019-10-19 18:22:05.672 INFO 13820 --- [ main] org.itstack.demo.DDDApplication : Starting DDDApplication on fuzhengwei-PC with PID 13820 (E:\itstack\itstack.org\itstack-demo-ddd-02\target\classes started by fuzhengwei in E:\itstack\itstack.org\itstack-demo-ddd-02)
2019-10-19 18:22:05.675 INFO 13820 --- [ main] org.itstack.demo.DDDApplication : No active profile set, falling back to default profiles: default
2019-10-19 18:22:05.952 INFO 13820 --- [ main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@3c4297f: startup date [Sat Oct 19 18:22:05 CST 2019]; root of context hierarchy
2019-10-19 18:22:07.756 INFO 13820 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2019-10-19 18:22:07.870 INFO 13820 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2019-10-19 18:22:07.870 INFO 13820 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.34
2019-10-19 18:22:07.896 INFO 13820 --- [ost-startStop-1] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [D:\Program Files Java\Java\jdk1.8.0_162\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\ProgramData\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;D:\Program Files Java\SlikSvn\bin;D:\Program Files Java\MySQL Server 5.1\bin;D:\Program Files Java\TortoiseGit\bin;D:\Program Files\nodejs\;D:\Program Files Java\Java\jdk1.6.0_24\bin;D:\Program Files Java\apache-maven-3.2.3\bin;C:\Users\fuzhengwei\AppData\Roaming\npm;D:\Program Files Java\Git\cmd;;.]
2019-10-19 18:22:08.040 INFO 13820 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2019-10-19 18:22:08.040 INFO 13820 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2088 ms
2019-10-19 18:22:08.102 INFO 13820 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]
2019-10-19 18:22:08.126 INFO 13820 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2019-10-19 18:22:08.127 INFO 13820 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2019-10-19 18:22:08.127 INFO 13820 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2019-10-19 18:22:08.127 INFO 13820 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2019-10-19 18:22:09.118 INFO 13820 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2019-10-19 18:22:09.383 INFO 13820 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@3c4297f: startup date [Sat Oct 19 18:22:05 CST 2019]; root of context hierarchy
2019-10-19 18:22:10.261 INFO 13820 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/tree/decisionRuleTree],methods=[POST]}" onto public org.springframework.http.ResponseEntity org.itstack.demo.interfaces.DDDController.decisionRuleTree(org.itstack.demo.interfaces.dto.DecisionMatterDTO)
2019-10-19 18:22:10.263 INFO 13820 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/tree/queryTreeSummaryInfo],methods=[POST]}" onto public org.springframework.http.ResponseEntity org.itstack.demo.interfaces.DDDController.queryTreeSummaryInfo(org.itstack.demo.interfaces.dto.TreeDTO)
2019-10-19 18:22:10.272 INFO 13820 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2019-10-19 18:22:10.274 INFO 13820 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2019-10-19 18:22:10.309 INFO 13820 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2019-10-19 18:22:10.309 INFO 13820 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2019-10-19 18:22:16.272 INFO 13820 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2019-10-19 18:22:16.273 INFO 13820 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Bean with name 'dataSource' has been autodetected for JMX exposure
2019-10-19 18:22:16.279 INFO 13820 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Located MBean 'dataSource': registering with JMX server as MBean [com.zaxxer.hikari:name=dataSource,type=HikariDataSource]
2019-10-19 18:22:16.375 INFO 13820 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2019-10-19 18:22:16.381 INFO 13820 --- [ main] org.itstack.demo.DDDApplication : Started DDDApplication in 11.458 seconds (JVM running for 20.584)
2019-10-19 18:22:31.336 INFO 13820 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
2019-10-19 18:22:31.336 INFO 13820 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
2019-10-19 18:22:31.372 INFO 13820 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 36 ms
2019-10-19 18:22:32.427 INFO 13820 --- [nio-8080-exec-1] o.itstack.demo.interfaces.DDDController : 規則樹行為信息決策10001Begin req:{"treeId":10001,"userId":"fuzhengwei","valMap":{"gender":"man","age":"25"}}
2019-10-19 18:22:32.508 INFO 13820 --- [nio-8080-exec-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2019-10-19 18:22:32.956 INFO 13820 --- [nio-8080-exec-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2019-10-19 18:22:33.028 INFO 13820 --- [nio-8080-exec-1] o.i.d.d.rule.service.engine.EngineBase : 樹引擎=>Test分類規則樹 userId:fuzhengwei treeId:10001 treeNode:11 ruleKey:userGender matterValue:man
2019-10-19 18:22:33.028 INFO 13820 --- [nio-8080-exec-1] o.i.d.d.rule.service.engine.EngineBase : 樹引擎=>Test分類規則樹 userId:fuzhengwei treeId:10001 treeNode:112 ruleKey:userAge matterValue:25
2019-10-19 18:22:33.039 INFO 13820 --- [nio-8080-exec-1] o.itstack.demo.interfaces.DDDController : 規則樹行為信息決策10001End res:{"treeId":10001,"nodeValue":"果實B","success":true,"nodeId":112,"userId":"fuzhengwei"}
2019-10-19 18:23:36.989 INFO 13820 --- [nio-8080-exec-5] o.itstack.demo.interfaces.DDDController : 查詢規則樹信息10001Begin req:{"treeId":10001}
2019-10-19 18:23:37.006 INFO 13820 --- [nio-8080-exec-5] o.itstack.demo.interfaces.DDDController : 查詢規則樹信息10001End res:{"treeInfo":{"treeId":10001,"treeName":"購物分類規則樹","treeDesc":"用于分類不同類型用戶可購物范圍","nodeCount":7,"lineCount":6},"treeRulePointList":[{"ruleDesc":"用戶性別[男/女]","ruleKey":"userGender"},{"ruleDesc":"用戶年齡","ruleKey":"userAge"}]}

綜上總結

  • 以上模擬購物場景下的規則處理抽象為樹決策引擎,以達到獨立領域服務。另外決策服務可以使用drools,任何抽象并不一定永遠使用,不要拘泥于一種形式。
  • 一些大型架構設計往往不是換一個設計模型就能徹底提升效率,還是需要人員整體素質,這是一個不斷培養的過程。
  • 領域驅動設計的思想并不只是教會程序猿寫代碼,也是非程序員以外的所有互聯網人員都適合學習的內容。
  • 家里住的舒適不舒適,并不一定取決于三居或者四居,大部分還是依賴于怎么對格局的布置。事必躬親、親力親為的精益求精之路,終究會讓你設計出更加合理的代碼。
責任編輯:武曉燕 來源: 今日頭條
相關推薦

2021-09-08 09:22:23

領域驅動設計

2024-12-31 11:05:07

2024-11-27 15:33:17

軟件架構DDD

2021-10-09 11:54:46

DDD微服務業務

2017-07-14 10:55:05

2020-09-02 08:12:05

CodeDDD代碼

2022-04-25 10:44:08

微服務架構設計

2024-11-08 08:37:25

2014-09-26 10:00:25

驅動設計DDD領域

2010-07-14 09:01:07

架構設計

2023-02-15 13:50:58

DDD戰略設計

2017-11-06 08:28:44

DDD架構設計IT

2022-07-17 07:37:29

微服務DDD工程化落地

2023-04-13 08:23:28

軟件架構設計

2021-06-07 09:33:21

企業架構驅動

2024-04-17 08:06:41

六邊形洋蔥架構領域

2024-07-17 08:12:06

2021-06-30 07:51:09

新項目領域建模

2022-04-11 09:15:00

前端開發技術

2025-10-10 02:12:00

性能優化C#ORM
點贊
收藏

51CTO技術棧公眾號

国产女人在线视频| 2017亚洲天堂| av人人综合网| 国产欧美一区二区精品秋霞影院| 国产精品第七影院| 91导航在线观看| 久久在线观看| 色久综合一二码| 在线成人av电影| 亚州av在线播放| 麻豆精品久久久| 午夜精品视频网站| 91香蕉国产视频| 红杏一区二区三区| 欧美在线你懂得| 日韩精品一区二区在线视频| 亚洲日本在线播放| 国产精品亚洲综合一区在线观看| 国产69精品久久久久9999| 少妇太紧太爽又黄又硬又爽小说| 韩国女主播一区二区三区| 精品视频免费在线| 2022亚洲天堂| 91cn在线观看| 国产精品久久久久久亚洲伦| 久久国产日韩欧美| 国产精品怡红院| 久久久久久久高潮| 久久久久亚洲精品国产| 少妇高潮惨叫久久久久| 少妇精品久久久| 亚洲国产精品成人av| 捷克做爰xxxⅹ性视频| 在线黄色的网站| 一区二区欧美国产| 中文网丁香综合网| 国产理论电影在线观看| 91浏览器在线视频| 国产日韩三区| 高h调教冰块play男男双性文| 蜜臀精品久久久久久蜜臀 | 色综合久久九月婷婷色综合| 欧美 日韩 国产精品| 巨大荫蒂视频欧美另类大| 国产欧美日韩在线看| 免费一区二区三区在在线视频| 亚洲黄色在线观看视频| 国产精品亚洲а∨天堂免在线| 国产欧美日韩中文字幕| 少妇又紧又色又爽又刺激视频 | 免费观看毛片网站| 国产91丝袜在线18| eeuss一区二区三区| 国产探花精品一区二区| 狠狠狠色丁香婷婷综合久久五月| 国产精品视频1区| www.久久网| 美女mm1313爽爽久久久蜜臀| 国产精品无码专区在线观看| 在线免费观看一区二区| 久久精品国产一区二区| 国产欧美在线视频| 国产精品羞羞答答在线| 国产一区二区导航在线播放| 亚洲一区二区三区在线视频 | 成人中文字幕电影| 国产精品一区二区欧美| 日本高清视频免费看| kk眼镜猥琐国模调教系列一区二区| 国产精品12| 日韩三级网址| 麻豆久久精品| 欧美在线观看网站| 国产精品第5页| 日日摸夜夜添夜夜添国产精品| 清纯唯美日韩制服另类| 欧美a视频在线观看| 久久综合伊人| 国产噜噜噜噜久久久久久久久| 怡红院男人天堂| 久久99精品视频| 91久久精品国产91久久性色tv| 99精品人妻无码专区在线视频区| 国产成人一区二区精品非洲| 国产伦精品一区| 国产在线观看黄| 黄色软件在线| 狠狠色2019综合网| 999在线观看免费大全电视剧| 后入内射欧美99二区视频| 99视频有精品| 涩涩涩999| 羞羞污视频在线观看| 亚洲国产欧美日韩另类综合| 欧美精品色婷婷五月综合| 国产69精品久久久久9999人| 欧美一级国产精品| 国产人妻人伦精品1国产丝袜| 欧美丝袜丝交足nylons172| 日韩中文在线视频| 久久久久无码国产精品不卡| 国产精品日韩| 91在线免费看网站| 亚洲欧美日韩免费| 中文字幕一区二区三区精华液| 人人妻人人澡人人爽欧美一区| 中文字幕成在线观看| 欧美丰满少妇xxxxx高潮对白| 国产精品一区二区人妻喷水| 日韩激情图片| 91av在线影院| www.天天干.com| 国产欧美精品区一区二区三区 | 成年人性生活视频| 精品视频97| 午夜精品福利在线观看| 伊人亚洲综合网| 久久九九久精品国产免费直播| 97精品国产97久久久久久粉红| 亚洲黄色免费av| 精品国产污污免费网站入口| 国产日韩欧美| 色综合色综合网色综合| 91丨九色丨海角社区| 成人综合在线观看| 超碰超碰超碰超碰超碰| 成人网ww555视频免费看| 亚洲精品久久7777777| 国产一区二区播放| 蜜桃视频在线一区| 欧美成人第一区| 精品精品导航| 日韩视频在线永久播放| 亚洲综合图片一区| 奇米影视在线99精品| 免费试看一区| 漫画在线观看av| 精品久久99ma| 精品无码人妻一区二区三| 激情图片小说一区| 亚洲在线欧美| 黄色成人在线观看网站| 成人另类视频| 亚洲人精品午夜在线观看| 黄色激情视频在线观看| а√中文在线资源库| 国产伦精品一区二区三区免费 | av资源久久| 欧美综合在线观看| 香蕉av一区二区三区| 亚洲成人av中文| 久久性爱视频网站| 亚洲大胆视频| 精品日韩电影| 亚洲第一av| 日韩av一区在线观看| 黄色片免费观看视频| 久久影视一区二区| 日本老熟妇毛茸茸| 欧美一二区在线观看| 国产精品高潮视频| 在线看的av网站| 欧美精品v日韩精品v韩国精品v| 国产免费嫩草影院| 激情综合五月婷婷| 日韩成人三级视频| 狠狠久久伊人| 国产精品电影在线观看| 日本中文字幕在线播放| 91精品国产福利| 久久精品波多野结衣| 风间由美一区二区三区在线观看| 东北少妇不带套对白| 人人精品亚洲| 国产精品白丝jk喷水视频一区| 国产色在线 com| 欧美疯狂做受xxxx富婆| 国产 日韩 欧美 成人| 91蝌蚪国产九色| 色www免费视频| 韩日精品视频| 欧美一区二区三区成人久久片| 97久久网站| 九九综合九九综合| 青青草在线免费观看| 精品视频色一区| 久久久无码一区二区三区| 久久这里只精品最新地址| 污污动漫在线观看| 亚洲激情不卡| 亚洲欧美日韩精品综合在线观看| 久久精品九色| 日本欧美中文字幕| 污污网站在线观看| 亚洲人成绝费网站色www| 国产乱码久久久久| 黑人精品xxx一区| 欧美另类videoxo高潮| 成人毛片老司机大片| 日本熟妇人妻中出| 亚洲国产精品第一区二区三区| 天天综合狠狠精品| 极品束缚调教一区二区网站| 国产欧美一区二区三区四区| 美女搞黄视频在线观看| 久久这里只有精品视频首页| 天天综合天天色| 日韩一区二区三区视频在线观看| 视频一区二区三区四区五区| 亚洲三级电影网站| 舐め犯し波多野结衣在线观看| 成人一区二区视频| 在线观看日本一区二区| 亚洲欧美日韩专区| 人妻无码一区二区三区四区| 欧美最新另类人妖| 狠狠色噜噜狠狠色综合久| 伊人久久大香| 日韩免费在线免费观看| 97人澡人人添人人爽欧美| 久久久国产成人精品| 成人在线视频成人| 亚洲精品网站在线播放gif| 亚洲成人中文字幕在线| 欧美日本在线播放| 又骚又黄的视频| 在线观看精品一区| 黄色av一级片| 欧美日韩午夜视频在线观看| 久久免费黄色网址| 亚洲欧美国产三级| 美女视频久久久| 中文字幕国产一区| 超碰人人人人人人人| 久久久精品日韩欧美| 亚洲国产精品成人综合久久久| 国产精品资源在线| 国产精品久久久久久9999| 久久精品噜噜噜成人av农村| 国产精品一区二区羞羞答答| 模特精品在线| 成年人免费在线播放| 亚洲一区二区三区高清| 青青草成人免费在线视频| 亚洲第一区色| 91视频 -- 69xx| 一区二区三区四区五区精品视频| 日本福利视频一区| 1024日韩| 毛片一区二区三区四区| 久久中文字幕一区二区三区| 欧洲熟妇精品视频| 日本不卡在线视频| 亚洲另类第一页| 麻豆成人av在线| 在线不卡一区二区三区| 国产在线播放一区三区四| 欧美高清精品一区二区| 国产精品18久久久久久vr| 26uuu国产| 本田岬高潮一区二区三区| 亚洲精品乱码久久久久久不卡 | 色欲狠狠躁天天躁无码中文字幕 | 激情综合色综合久久综合| av在线网站免费观看| 国产成a人无v码亚洲福利| 毛茸茸free性熟hd| 久久久久久久网| 一本色道久久88| 亚洲精品va在线观看| 日韩女优在线观看| 色婷婷av久久久久久久| 亚洲在线观看av| 日韩美女一区二区三区四区| 欧美 日韩 国产 在线| 日韩国产精品亚洲а∨天堂免| 天堂网av在线播放| 国产性色av一区二区| 久久精品视频观看| 性欧美xxxx交| 影视一区二区三区| 91情侣在线视频| 欧美日韩麻豆| 一区二区不卡在线视频 午夜欧美不卡' | 伊人色综合一区二区三区影院视频| 热99在线视频| 999色成人| 久久精品国产一区二区三区日韩| gogogo高清在线观看一区二区| 国产精品jizz在线观看老狼| 亚洲第一黄色| 久热精品在线观看视频| 国产91丝袜在线观看| 国产探花视频在线播放| 亚洲综合一区二区精品导航| 欧美日韩一级黄色片| 日韩欧美区一区二| 成人激情电影在线看| 欧美精品国产精品日韩精品| 欧美色片在线观看| 国产精品一区二区免费| 91久久国产| 欧美 国产 小说 另类| 男人亚洲天堂| 深夜精品寂寞黄网站在线观看| 男人天堂亚洲| 国产美女主播一区| 你懂的在线观看一区二区| 亚洲一区二区三区精品视频| 宅男噜噜噜66国产日韩在线观看| 亚洲一区二区福利视频| 91蜜桃视频在线| 欧美成人三级在线观看| 欧美写真视频网站| 手机在线观看毛片| 欧美另类在线播放| 激情中国色综合| 欧美精品亚洲精品| 韩日成人av| 久久久福利影院| 欧美韩国一区二区| 国产精品第5页| 亚洲激情小视频| 四季久久免费一区二区三区四区| 国产精品国模在线| 亚洲另类春色校园小说| 日本精品久久久久久久久久| 精品亚洲国内自在自线福利| 玖玖爱在线观看| 午夜伊人狠狠久久| 性一交一乱一透一a级| www国产精品视频| 成人激情视屏| 婷婷久久伊人| 久久精品主播| 亚洲最大成人网站| 精品福利免费观看| 天天干天天操av| 97在线免费观看| 卡一精品卡二卡三网站乱码| 欧美一区二区激情| 国产91丝袜在线播放| 久久久久久久九九九九| 日韩手机在线导航| 国产网红女主播精品视频| 91福利视频导航| 欧美视频亚洲视频| 四虎成人免费视频| 午夜不卡在线视频| 性感美女一级片| 欧美壮男野外gaytube| 九一国产精品| 欧美精品aaaa| 国产精品久久影院| 国产农村老头老太视频| 久久视频在线看| 日韩亚洲精品在线观看| 欧美高清中文字幕| av一本久道久久综合久久鬼色| 丰满少妇乱子伦精品看片| 精品视频一区在线视频| 国产经典一区| 懂色av一区二区三区四区五区| 国产综合色视频| 久久久美女视频| 亚洲欧美另类中文字幕| 91天天综合| 女人床在线观看| 91视频一区二区三区| 99久久久无码国产精品免费蜜柚| 伊人一区二区三区久久精品| 日本免费在线一区| 国产激情片在线观看| 99re热这里只有精品视频| 在线免费观看av网址| 精品国产依人香蕉在线精品| 亚洲精品一区国产| 91黄色小网站| 亚洲欧洲色图综合| 国内爆初菊对白视频| 日韩美女主播视频| 亚洲高清影视| 中文成人无字幕乱码精品区| 在线观看视频一区二区欧美日韩| 国内精品不卡| 国产一区二区精品在线| 日本在线不卡视频一二三区| 丁香花五月激情| 精品夜色国产国偷在线| 日韩美香港a一级毛片| 国产免费黄色一级片| 日本一区二区三区国色天香| www.久久综合| 国产精品白嫩美女在线观看 | 日韩中文字幕av| 国产精品x8x8一区二区| 奇米影音第四色| 午夜久久久久久久久| 亚洲s色大片| 久久手机视频|