Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
檀越@新空间
design
提交
5d62c194
D
design
项目概览
檀越@新空间
/
design
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
design
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
5d62c194
编写于
9月 27, 2022
作者:
Q
qinyingjie
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Initial commit
上级
变更
66
隐藏空白更改
内联
并排
Showing
66 changed file
with
2040 addition
and
0 deletion
+2040
-0
.gitignore
.gitignore
+33
-0
pom.xml
pom.xml
+50
-0
src/main/java/com/study/design/DesignApplication.java
src/main/java/com/study/design/DesignApplication.java
+13
-0
src/main/java/com/study/design/MockDb.java
src/main/java/com/study/design/MockDb.java
+40
-0
src/main/java/com/study/design/auditlog/AbstractAuditLogProcessor.java
.../com/study/design/auditlog/AbstractAuditLogProcessor.java
+27
-0
src/main/java/com/study/design/auditlog/LoginLogProcessor.java
...ain/java/com/study/design/auditlog/LoginLogProcessor.java
+12
-0
src/main/java/com/study/design/auditlog/OrderLogProcessor.java
...ain/java/com/study/design/auditlog/OrderLogProcessor.java
+16
-0
src/main/java/com/study/design/auditlog/PayLogProcessor.java
src/main/java/com/study/design/auditlog/PayLogProcessor.java
+16
-0
src/main/java/com/study/design/auditlog/pojo/AuditLog.java
src/main/java/com/study/design/auditlog/pojo/AuditLog.java
+63
-0
src/main/java/com/study/design/controller/EsController.java
src/main/java/com/study/design/controller/EsController.java
+20
-0
src/main/java/com/study/design/controller/ItemController.java
...main/java/com/study/design/controller/ItemController.java
+33
-0
src/main/java/com/study/design/controller/OrderController.java
...ain/java/com/study/design/controller/OrderController.java
+37
-0
src/main/java/com/study/design/controller/UserController.java
...main/java/com/study/design/controller/UserController.java
+36
-0
src/main/java/com/study/design/esquery/EsQueryProcessor.java
src/main/java/com/study/design/esquery/EsQueryProcessor.java
+80
-0
src/main/java/com/study/design/esquery/EsSqlQuery.java
src/main/java/com/study/design/esquery/EsSqlQuery.java
+43
-0
src/main/java/com/study/design/esquery/EsSqlResult.java
src/main/java/com/study/design/esquery/EsSqlResult.java
+34
-0
src/main/java/com/study/design/handler/AbstractSuggestRequirementHandler.java
...udy/design/handler/AbstractSuggestRequirementHandler.java
+9
-0
src/main/java/com/study/design/handler/CityCheckHandler.java
src/main/java/com/study/design/handler/CityCheckHandler.java
+16
-0
src/main/java/com/study/design/handler/NewCheckHandler.java
src/main/java/com/study/design/handler/NewCheckHandler.java
+18
-0
src/main/java/com/study/design/handler/PersonnalCheckHandler.java
.../java/com/study/design/handler/PersonnalCheckHandler.java
+16
-0
src/main/java/com/study/design/handler/RecentCheckHandler.java
...ain/java/com/study/design/handler/RecentCheckHandler.java
+16
-0
src/main/java/com/study/design/handler/SuggestRequirementHandlerProcess.java
...tudy/design/handler/SuggestRequirementHandlerProcess.java
+28
-0
src/main/java/com/study/design/items/node/AbstractProductItem.java
...java/com/study/design/items/node/AbstractProductItem.java
+6
-0
src/main/java/com/study/design/items/node/ProductItem.java
src/main/java/com/study/design/items/node/ProductItem.java
+55
-0
src/main/java/com/study/design/items/visitor/AddItemVisitor.java
...n/java/com/study/design/items/visitor/AddItemVisitor.java
+34
-0
src/main/java/com/study/design/items/visitor/DelItemVisitor.java
...n/java/com/study/design/items/visitor/DelItemVisitor.java
+34
-0
src/main/java/com/study/design/items/visitor/ItemVisitor.java
...main/java/com/study/design/items/visitor/ItemVisitor.java
+7
-0
src/main/java/com/study/design/order/OrderStateListener.java
src/main/java/com/study/design/order/OrderStateListener.java
+34
-0
src/main/java/com/study/design/order/config/OrderStateMachineConfig.java
...om/study/design/order/config/OrderStateMachineConfig.java
+58
-0
src/main/java/com/study/design/order/pojo/Order.java
src/main/java/com/study/design/order/pojo/Order.java
+24
-0
src/main/java/com/study/design/order/pojo/OrderState.java
src/main/java/com/study/design/order/pojo/OrderState.java
+8
-0
src/main/java/com/study/design/order/pojo/OrderStateChangeAction.java
...a/com/study/design/order/pojo/OrderStateChangeAction.java
+7
-0
src/main/java/com/study/design/pay/additionalDecorator/AbstractAddFuncDecorator.java
...ign/pay/additionalDecorator/AbstractAddFuncDecorator.java
+24
-0
src/main/java/com/study/design/pay/additionalDecorator/AddFuncDecorator.java
...tudy/design/pay/additionalDecorator/AddFuncDecorator.java
+40
-0
src/main/java/com/study/design/pay/facade/StrategyFacade.java
...main/java/com/study/design/pay/facade/StrategyFacade.java
+54
-0
src/main/java/com/study/design/pay/factory/AddFuncFactory.java
...ain/java/com/study/design/pay/factory/AddFuncFactory.java
+23
-0
src/main/java/com/study/design/pay/factory/StrategyFactory.java
...in/java/com/study/design/pay/factory/StrategyFactory.java
+39
-0
src/main/java/com/study/design/pay/pojo/PayBody.java
src/main/java/com/study/design/pay/pojo/PayBody.java
+40
-0
src/main/java/com/study/design/pay/proxy/ContextProxy.java
src/main/java/com/study/design/pay/proxy/ContextProxy.java
+18
-0
src/main/java/com/study/design/pay/strategy/BkPayStrategy.java
...ain/java/com/study/design/pay/strategy/BkPayStrategy.java
+11
-0
src/main/java/com/study/design/pay/strategy/PayStrategy.java
src/main/java/com/study/design/pay/strategy/PayStrategy.java
+22
-0
src/main/java/com/study/design/pay/strategy/WcPayStrategy.java
...ain/java/com/study/design/pay/strategy/WcPayStrategy.java
+11
-0
src/main/java/com/study/design/pay/strategy/ZfbPayStrategy.java
...in/java/com/study/design/pay/strategy/ZfbPayStrategy.java
+11
-0
src/main/java/com/study/design/pay/strategyContext/AbstractPayContext.java
.../study/design/pay/strategyContext/AbstractPayContext.java
+7
-0
src/main/java/com/study/design/pay/strategyContext/PayContext.java
...java/com/study/design/pay/strategyContext/PayContext.java
+26
-0
src/main/java/com/study/design/pay/strategyEnum/StrategyEnum.java
.../java/com/study/design/pay/strategyEnum/StrategyEnum.java
+15
-0
src/main/java/com/study/design/pojo/TicketParam.java
src/main/java/com/study/design/pojo/TicketParam.java
+43
-0
src/main/java/com/study/design/pojo/UserInfo.java
src/main/java/com/study/design/pojo/UserInfo.java
+42
-0
src/main/java/com/study/design/service/EsService.java
src/main/java/com/study/design/service/EsService.java
+26
-0
src/main/java/com/study/design/service/ItemService.java
src/main/java/com/study/design/service/ItemService.java
+41
-0
src/main/java/com/study/design/service/OrderService.java
src/main/java/com/study/design/service/OrderService.java
+108
-0
src/main/java/com/study/design/service/UserService.java
src/main/java/com/study/design/service/UserService.java
+72
-0
src/main/java/com/study/design/ticket/TicketConstant.java
src/main/java/com/study/design/ticket/TicketConstant.java
+17
-0
src/main/java/com/study/design/ticket/builder/CompanyTicketBuilder.java
...com/study/design/ticket/builder/CompanyTicketBuilder.java
+38
-0
src/main/java/com/study/design/ticket/builder/PersonalTicketBuilder.java
...om/study/design/ticket/builder/PersonalTicketBuilder.java
+35
-0
src/main/java/com/study/design/ticket/builder/TicketBuilder.java
...n/java/com/study/design/ticket/builder/TicketBuilder.java
+11
-0
src/main/java/com/study/design/ticket/pojo/CompanyTicket.java
...main/java/com/study/design/ticket/pojo/CompanyTicket.java
+80
-0
src/main/java/com/study/design/ticket/pojo/PersonalTicket.java
...ain/java/com/study/design/ticket/pojo/PersonalTicket.java
+71
-0
src/main/java/login/implementor/LoginFunc.java
src/main/java/login/implementor/LoginFunc.java
+5
-0
src/main/java/login/implementor/WbLoginFunc.java
src/main/java/login/implementor/WbLoginFunc.java
+10
-0
src/main/java/login/implementor/ZfbLoginFunc.java
src/main/java/login/implementor/ZfbLoginFunc.java
+10
-0
src/main/java/login/implementor/abstractlogin/AbstractLoginProcessor.java
...gin/implementor/abstractlogin/AbstractLoginProcessor.java
+13
-0
src/main/java/login/implementor/abstractlogin/ThirdPartLogin.java
.../java/login/implementor/abstractlogin/ThirdPartLogin.java
+15
-0
src/main/resources/application.properties
src/main/resources/application.properties
+4
-0
src/main/resources/test
src/main/resources/test
+122
-0
src/test/java/com/study/design/DesignApplicationTests.java
src/test/java/com/study/design/DesignApplicationTests.java
+13
-0
未找到文件。
.gitignore
0 → 100644
浏览文件 @
5d62c194
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
pom.xml
0 → 100644
浏览文件 @
5d62c194
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>
4.0.0
</modelVersion>
<parent>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-parent
</artifactId>
<version>
2.7.3
</version>
<relativePath/>
<!-- lookup parent from repository -->
</parent>
<groupId>
com.study
</groupId>
<artifactId>
design
</artifactId>
<version>
0.0.1-SNAPSHOT
</version>
<name>
design
</name>
<description>
Demo project for Spring Boot
</description>
<properties>
<java.version>
1.8
</java.version>
</properties>
<dependencies>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter
</artifactId>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-web
</artifactId>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-test
</artifactId>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
org.springframework.statemachine
</groupId>
<artifactId>
spring-statemachine-core
</artifactId>
<version>
2.1.3.RELEASE
</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-maven-plugin
</artifactId>
</plugin>
</plugins>
</build>
</project>
src/main/java/com/study/design/DesignApplication.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design
;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.boot.autoconfigure.SpringBootApplication
;
@SpringBootApplication
public
class
DesignApplication
{
public
static
void
main
(
String
[]
args
)
{
SpringApplication
.
run
(
DesignApplication
.
class
,
args
);
}
}
src/main/java/com/study/design/MockDb.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design
;
import
com.study.design.items.node.ProductItem
;
import
java.util.ArrayList
;
import
java.util.List
;
public
class
MockDb
{
public
static
ProductItem
ProductItem
=
new
ProductItem
();
static
{
ProductItem
.
setId
(
1
);
ProductItem
.
setPid
(
0
);
ProductItem
.
setName
(
"书籍"
);
List
<
ProductItem
>
child
=
new
ArrayList
<>();
ProductItem
c1
=
new
ProductItem
();
c1
.
setId
(
2
);
c1
.
setPid
(
1
);
c1
.
setName
(
"技术书籍"
);
ProductItem
c2
=
new
ProductItem
();
c2
.
setId
(
3
);
c2
.
setPid
(
1
);
c2
.
setName
(
"历史书籍"
);
List
<
ProductItem
>
child1
=
new
ArrayList
<>();
ProductItem
c3
=
new
ProductItem
();
c3
.
setId
(
4
);
c3
.
setPid
(
2
);
c3
.
setName
(
"并发编程"
);
ProductItem
c4
=
new
ProductItem
();
c4
.
setId
(
5
);
c4
.
setPid
(
2
);
c4
.
setName
(
"JVM"
);
child1
.
add
(
c3
);
child1
.
add
(
c4
);
c1
.
setChild
(
child1
);
child
.
add
(
c1
);
child
.
add
(
c2
);
ProductItem
.
setChild
(
child
);
}
}
src/main/java/com/study/design/auditlog/AbstractAuditLogProcessor.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.auditlog
;
import
com.study.design.auditlog.pojo.AuditLog
;
import
java.util.Date
;
public
abstract
class
AbstractAuditLogProcessor
{
// 创建我们的 AuditLog (基础部分)
public
final
AuditLog
buildAuditLog
(
String
account
,
String
action
,
String
orderId
){
AuditLog
auditLog
=
new
AuditLog
();
auditLog
.
setAccount
(
account
);
auditLog
.
setAction
(
action
);
auditLog
.
setOrderId
(
orderId
);
auditLog
.
setDate
(
new
Date
());
return
auditLog
;
}
protected
abstract
AuditLog
buildDetails
(
AuditLog
auditLog
);
public
final
void
sendToQueue
(
AuditLog
auditLog
)
{
//send toQueue(auditLog)
}
public
final
void
processAuditLog
(
String
account
,
String
action
,
String
orderId
)
{
this
.
sendToQueue
(
buildDetails
(
buildAuditLog
(
account
,
action
,
orderId
)));
}
}
src/main/java/com/study/design/auditlog/LoginLogProcessor.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.auditlog
;
import
com.study.design.auditlog.pojo.AuditLog
;
import
org.springframework.stereotype.Component
;
@Component
public
class
LoginLogProcessor
extends
AbstractAuditLogProcessor
{
@Override
protected
AuditLog
buildDetails
(
AuditLog
auditLog
)
{
return
auditLog
;
}
}
src/main/java/com/study/design/auditlog/OrderLogProcessor.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.auditlog
;
import
com.study.design.auditlog.pojo.AuditLog
;
import
org.springframework.stereotype.Component
;
@Component
public
class
OrderLogProcessor
extends
AbstractAuditLogProcessor
{
@Override
protected
AuditLog
buildDetails
(
AuditLog
auditLog
)
{
String
orderId
=
auditLog
.
getOrderId
();
String
productDetails
=
"通过 orderId 获取"
;
auditLog
.
setDetails
(
productDetails
);
System
.
out
.
println
(
auditLog
);
return
auditLog
;
}
}
src/main/java/com/study/design/auditlog/PayLogProcessor.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.auditlog
;
import
com.study.design.auditlog.pojo.AuditLog
;
import
org.springframework.stereotype.Component
;
@Component
public
class
PayLogProcessor
extends
AbstractAuditLogProcessor
{
@Override
protected
AuditLog
buildDetails
(
AuditLog
auditLog
)
{
String
orderId
=
auditLog
.
getOrderId
();
String
allDetails
=
"通过 orderId 或者是参数 获取产品信息,金额,支付方式"
;
auditLog
.
setDetails
(
allDetails
);
System
.
out
.
println
(
auditLog
);
return
auditLog
;
}
}
src/main/java/com/study/design/auditlog/pojo/AuditLog.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.auditlog.pojo
;
import
java.util.Date
;
public
class
AuditLog
{
private
String
account
;
private
String
action
;
private
Date
date
;
private
String
orderId
;
private
Object
details
;
//订单创建需要有相关产品信息;
// 订单支付需要有相关产品信息以及支付方式和支付金额。
public
String
getAccount
()
{
return
account
;
}
public
void
setAccount
(
String
account
)
{
this
.
account
=
account
;
}
public
String
getAction
()
{
return
action
;
}
public
void
setAction
(
String
action
)
{
this
.
action
=
action
;
}
public
Date
getDate
()
{
return
date
;
}
public
void
setDate
(
Date
date
)
{
this
.
date
=
date
;
}
public
String
getOrderId
()
{
return
orderId
;
}
public
void
setOrderId
(
String
orderId
)
{
this
.
orderId
=
orderId
;
}
public
Object
getDetails
()
{
return
details
;
}
public
void
setDetails
(
Object
details
)
{
this
.
details
=
details
;
}
@Override
public
String
toString
()
{
return
"AuditLog{"
+
"account='"
+
account
+
'\''
+
", action='"
+
action
+
'\''
+
", date="
+
date
+
", orderId='"
+
orderId
+
'\''
+
", details="
+
details
+
'}'
;
}
}
src/main/java/com/study/design/controller/EsController.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.controller
;
import
com.study.design.service.EsService
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.bind.annotation.RestController
;
@RestController
public
class
EsController
{
@Autowired
private
EsService
esService
;
@PostMapping
(
"es"
)
public
Boolean
query
(
@RequestParam
String
query
,
Long
fetchSize
)
{
return
esService
.
query
(
query
,
fetchSize
);
}
}
src/main/java/com/study/design/controller/ItemController.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.controller
;
import
com.study.design.items.node.ProductItem
;
import
com.study.design.service.EsService
;
import
com.study.design.service.ItemService
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.bind.annotation.RestController
;
@RestController
public
class
ItemController
{
@Autowired
private
ItemService
itemService
;
@GetMapping
(
"get"
)
public
ProductItem
getItem
()
{
return
itemService
.
getItem
();
}
@PostMapping
(
"del"
)
public
ProductItem
delItem
(
@RequestBody
ProductItem
productItem
)
{
return
itemService
.
delItem
(
productItem
);
}
@PostMapping
(
"add"
)
public
ProductItem
addItem
(
@RequestBody
ProductItem
productItem
)
{
return
itemService
.
addItem
(
productItem
);
}
}
src/main/java/com/study/design/controller/OrderController.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.controller
;
import
com.study.design.order.pojo.Order
;
import
com.study.design.pay.pojo.PayBody
;
import
com.study.design.service.OrderService
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.bind.annotation.RestController
;
@RestController
public
class
OrderController
{
@Autowired
private
OrderService
orderService
;
@GetMapping
(
"mkOrder"
)
public
Order
createOrder
(
@RequestParam
Integer
oid
)
{
return
orderService
.
createOrder
(
oid
);
}
@PostMapping
(
"/pay"
)
public
Order
payOrder
(
@RequestBody
PayBody
payBody
){
return
orderService
.
pay
(
payBody
);
}
@GetMapping
(
"/send"
)
public
Order
send
(
@RequestParam
Integer
oid
)
{
return
orderService
.
send
(
oid
);
}
@GetMapping
(
"/receive"
)
public
Order
receive
(
@RequestParam
Integer
oid
)
{
return
orderService
.
receive
(
oid
);
}
}
src/main/java/com/study/design/controller/UserController.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.controller
;
import
com.study.design.pojo.TicketParam
;
import
com.study.design.service.UserService
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
@RestController
public
class
UserController
{
@Autowired
private
UserService
userService
;
@GetMapping
(
"/suggest"
)
public
List
<
String
>
suggestRequirement
(
@RequestParam
String
username
)
{
return
userService
.
suggestRequirement
(
username
);
}
@PostMapping
(
"/ticket"
)
public
Object
getTicket
(
@RequestBody
TicketParam
ticketParam
)
{
return
userService
.
getTicket
(
ticketParam
);
}
@PostMapping
(
"/login"
)
public
Boolean
login
(
@RequestParam
String
name
,
@RequestParam
String
pwd
,
@RequestParam
String
type
)
{
return
userService
.
login
(
name
,
pwd
,
type
);
}
}
src/main/java/com/study/design/esquery/EsQueryProcessor.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.esquery
;
import
org.springframework.stereotype.Component
;
import
org.springframework.web.client.RestTemplate
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Spliterators
;
import
java.util.stream.Collectors
;
import
java.util.stream.Stream
;
import
java.util.stream.StreamSupport
;
@Component
public
class
EsQueryProcessor
{
//1. 我们要用stream 返回 为了节省内存
public
Stream
<
Map
<
String
,
Object
>>
scrollEsStream
(
String
query
,
Long
fetchSize
)
{
return
StreamSupport
.
stream
(
Spliterators
.
spliteratorUnknownSize
(
new
ScrollIterator
(
query
,
fetchSize
),
0
),
false
);
}
//2. 我们要 迭代器
private
class
ScrollIterator
implements
Iterator
<
Map
<
String
,
Object
>>
{
private
String
scrollId
;
private
List
<
String
>
columns
;
Iterator
<
Map
<
String
,
Object
>>
iterator
;
RestTemplate
restTemplate
=
new
RestTemplate
();
// 真是项目中使用resttemplate的时候
//一定是进行过我们的 bean 配置注入的。这里边直接用new关键字是为了访问我们的es 接口。
//构造函数进行第一次查询,并且初始化我们后续需要使用的 columns 和 iterator 和 scroll
public
ScrollIterator
(
String
query
,
Long
fetchSize
)
{
EsSqlResult
esSqlResult
=
restTemplate
.
postForObject
(
"http://localhost:9200/_sql?format=json"
,
new
EsSqlQuery
(
query
,
fetchSize
),
EsSqlResult
.
class
);
//第一次访问的结果出来了
this
.
scrollId
=
esSqlResult
.
getCursor
();
this
.
columns
=
esSqlResult
.
getColumns
()
.
stream
().
map
(
x
->
x
.
get
(
"name"
))
.
collect
(
Collectors
.
toList
());
this
.
iterator
=
convert
(
columns
,
esSqlResult
).
iterator
();
}
// hasNext 根据 是否 scrollId 为null进行后续的 第二次,第三次,,,的访问,直到 scrollId 为null
@Override
public
boolean
hasNext
()
{
return
iterator
.
hasNext
()
||
scrollNext
();
}
private
boolean
scrollNext
()
{
if
(
iterator
==
null
||
this
.
scrollId
==
null
)
{
return
false
;
}
EsSqlResult
esSqlResult
=
restTemplate
.
postForObject
(
"http://localhost:9200/_sql?format=json"
,
new
EsSqlQuery
(
this
.
scrollId
),
EsSqlResult
.
class
);
//第二次访问的结果出来了
this
.
scrollId
=
esSqlResult
.
getCursor
();
this
.
iterator
=
convert
(
columns
,
esSqlResult
).
iterator
();
return
iterator
.
hasNext
();
}
@Override
public
Map
<
String
,
Object
>
next
()
{
return
iterator
.
next
();
}
}
//3. 返回结果传统一点 List<map>
private
List
<
Map
<
String
,
Object
>>
convert
(
List
<
String
>
columns
,
EsSqlResult
esSqlResult
)
{
List
<
Map
<
String
,
Object
>>
results
=
new
ArrayList
<>();
for
(
List
<
Object
>
row
:
esSqlResult
.
getRows
())
{
Map
<
String
,
Object
>
map
=
new
HashMap
<>();
for
(
int
i
=
0
;
i
<
columns
.
size
();
i
++)
{
map
.
put
(
columns
.
get
(
i
),
row
.
get
(
i
));
}
results
.
add
(
map
);
}
return
results
;
}
}
src/main/java/com/study/design/esquery/EsSqlQuery.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.esquery
;
import
com.fasterxml.jackson.annotation.JsonIgnoreProperties
;
@JsonIgnoreProperties
public
class
EsSqlQuery
{
private
String
query
;
private
Long
fetchSize
;
private
String
cursor
;
public
EsSqlQuery
(
String
cursor
)
{
this
.
cursor
=
cursor
;
}
public
EsSqlQuery
(
String
query
,
Long
fetchSize
)
{
this
.
query
=
query
;
this
.
fetchSize
=
fetchSize
;
}
public
String
getQuery
()
{
return
query
;
}
public
void
setQuery
(
String
query
)
{
this
.
query
=
query
;
}
public
Long
getFetchSize
()
{
return
fetchSize
;
}
public
void
setFetchSize
(
Long
fetchSize
)
{
this
.
fetchSize
=
fetchSize
;
}
public
String
getCursor
()
{
return
cursor
;
}
public
void
setCursor
(
String
cursor
)
{
this
.
cursor
=
cursor
;
}
}
src/main/java/com/study/design/esquery/EsSqlResult.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.esquery
;
import
java.util.List
;
import
java.util.Map
;
public
class
EsSqlResult
{
private
List
<
Map
<
String
,
String
>>
columns
;
private
List
<
List
<
Object
>>
rows
;
private
String
cursor
;
public
List
<
Map
<
String
,
String
>>
getColumns
()
{
return
columns
;
}
public
void
setColumns
(
List
<
Map
<
String
,
String
>>
columns
)
{
this
.
columns
=
columns
;
}
public
List
<
List
<
Object
>>
getRows
()
{
return
rows
;
}
public
void
setRows
(
List
<
List
<
Object
>>
rows
)
{
this
.
rows
=
rows
;
}
public
String
getCursor
()
{
return
cursor
;
}
public
void
setCursor
(
String
cursor
)
{
this
.
cursor
=
cursor
;
}
}
src/main/java/com/study/design/handler/AbstractSuggestRequirementHandler.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.handler
;
import
com.study.design.pojo.UserInfo
;
import
java.util.List
;
public
abstract
class
AbstractSuggestRequirementHandler
{
abstract
void
processHandler
(
UserInfo
userInfo
,
List
<
String
>
suggestLists
);
}
src/main/java/com/study/design/handler/CityCheckHandler.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.handler
;
import
com.study.design.pojo.UserInfo
;
import
java.util.List
;
public
class
CityCheckHandler
extends
AbstractSuggestRequirementHandler
{
@Override
public
void
processHandler
(
UserInfo
userInfo
,
List
<
String
>
suggestLists
)
{
//通过获取 userinfo 的 city 属性
String
city
=
userInfo
.
getCity
();
// 通过city 和 之前保留的 4 个 业务信息进行对比。然后筛选出剩余的 3 个 业务投放
suggestLists
.
remove
(
"1"
);
}
}
src/main/java/com/study/design/handler/NewCheckHandler.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.handler
;
import
com.study.design.pojo.UserInfo
;
import
com.sun.org.apache.bcel.internal.generic.NEW
;
import
java.util.ArrayList
;
import
java.util.List
;
public
class
NewCheckHandler
extends
AbstractSuggestRequirementHandler
{
@Override
public
void
processHandler
(
UserInfo
userInfo
,
List
<
String
>
suggestLists
)
{
//通过获取 userinfo 的 buyProducts 属性
boolean
newUser
=
userInfo
.
isNewUser
();
if
(
newUser
)
{
suggestLists
=
new
ArrayList
<>();
// 特定的新用户奖励
}
}
}
src/main/java/com/study/design/handler/PersonnalCheckHandler.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.handler
;
import
com.study.design.pojo.UserInfo
;
import
java.util.List
;
public
class
PersonnalCheckHandler
extends
AbstractSuggestRequirementHandler
{
@Override
public
void
processHandler
(
UserInfo
userInfo
,
List
<
String
>
suggestLists
)
{
// 通过个人资质的check,我们找到了 4 个可以投放的业务。放到 suggestLists 中。
suggestLists
.
add
(
"1"
);
suggestLists
.
add
(
"2"
);
suggestLists
.
add
(
"3"
);
suggestLists
.
add
(
"4"
);
}
}
src/main/java/com/study/design/handler/RecentCheckHandler.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.handler
;
import
com.study.design.pojo.UserInfo
;
import
java.util.List
;
public
class
RecentCheckHandler
extends
AbstractSuggestRequirementHandler
{
@Override
public
void
processHandler
(
UserInfo
userInfo
,
List
<
String
>
suggestLists
)
{
//通过获取 userinfo 的 buyProducts 属性
List
<
String
>
buyProducts
=
userInfo
.
getBuyProducts
();
// buyProducts 和 之前保留的 3 个 业务信息进行对比。然后筛选出剩余的 2 个 业务投放
suggestLists
.
remove
(
"2"
);
}
}
src/main/java/com/study/design/handler/SuggestRequirementHandlerProcess.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.handler
;
import
com.study.design.pojo.UserInfo
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Component
;
import
java.util.List
;
@Component
public
class
SuggestRequirementHandlerProcess
{
@Value
(
"#{'${suggest.requirement.handler}'.split(',')}"
)
private
List
<
String
>
handlers
;
public
void
process
(
UserInfo
userInfo
,
List
<
String
>
suggestLists
)
{
// 如果想要实时的进行顺序的调整或者是增减。那必须要使用配置中心进行配置。
// 比如springcloud里边自带的 git 的这种配置中心; applo 配置中心。
try
{
for
(
String
handler
:
handlers
)
{
AbstractSuggestRequirementHandler
handle
=
(
AbstractSuggestRequirementHandler
)
Class
.
forName
(
handler
).
newInstance
();
handle
.
processHandler
(
userInfo
,
suggestLists
);
}
}
catch
(
Exception
e
)
{
}
}
}
src/main/java/com/study/design/items/node/AbstractProductItem.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.items.node
;
public
abstract
class
AbstractProductItem
{
public
abstract
void
removeChild
(
AbstractProductItem
item
);
public
abstract
void
addChild
(
AbstractProductItem
item
);
}
src/main/java/com/study/design/items/node/ProductItem.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.items.node
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.stream.Collectors
;
public
class
ProductItem
extends
AbstractProductItem
{
private
int
id
;
private
int
pid
;
private
String
name
;
private
List
<
ProductItem
>
child
=
new
ArrayList
<>();
@Override
public
void
removeChild
(
AbstractProductItem
item
)
{
ProductItem
removeItem
=
(
ProductItem
)
item
;
this
.
child
=
child
.
stream
().
filter
(
x
->
x
.
getId
()
!=
removeItem
.
getId
()).
collect
(
Collectors
.
toList
());
}
@Override
public
void
addChild
(
AbstractProductItem
item
)
{
this
.
child
.
add
((
ProductItem
)
item
);
}
public
int
getId
()
{
return
id
;
}
public
void
setId
(
int
id
)
{
this
.
id
=
id
;
}
public
int
getPid
()
{
return
pid
;
}
public
void
setPid
(
int
pid
)
{
this
.
pid
=
pid
;
}
public
String
getName
()
{
return
name
;
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
public
List
<
ProductItem
>
getChild
()
{
return
child
;
}
public
void
setChild
(
List
<
ProductItem
>
child
)
{
this
.
child
=
child
;
}
}
src/main/java/com/study/design/items/visitor/AddItemVisitor.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.items.visitor
;
import
com.study.design.MockDb
;
import
com.study.design.items.node.ProductItem
;
import
org.springframework.stereotype.Component
;
@Component
public
class
AddItemVisitor
implements
ItemVisitor
<
ProductItem
>{
// 入参是 id 2, pid为 1
@Override
public
ProductItem
visitor
(
ProductItem
productItem
)
{
ProductItem
currentItem
=
MockDb
.
ProductItem
;
// 从缓存来的 to do
if
(
productItem
.
getId
()
==
currentItem
.
getId
())
{
throw
new
UnsupportedOperationException
(
"根节点是唯一的。"
);
}
if
(
productItem
.
getPid
()
==
currentItem
.
getId
())
{
currentItem
.
addChild
(
productItem
);
return
currentItem
;
}
addChild
(
productItem
,
currentItem
);
return
currentItem
;
}
private
void
addChild
(
ProductItem
productItem
,
ProductItem
currentItem
)
{
for
(
ProductItem
item
:
currentItem
.
getChild
())
{
if
(
item
.
getId
()
==
productItem
.
getPid
())
{
item
.
addChild
(
productItem
);
break
;
}
else
{
addChild
(
productItem
,
item
);
}
}
}
}
src/main/java/com/study/design/items/visitor/DelItemVisitor.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.items.visitor
;
import
com.study.design.MockDb
;
import
com.study.design.items.node.ProductItem
;
import
org.springframework.stereotype.Component
;
@Component
public
class
DelItemVisitor
implements
ItemVisitor
<
ProductItem
>{
// 入参是 id 2, pid为 1
@Override
public
ProductItem
visitor
(
ProductItem
productItem
)
{
ProductItem
currentItem
=
MockDb
.
ProductItem
;
// 从缓存来的 to do
if
(
productItem
.
getId
()
==
currentItem
.
getId
())
{
throw
new
UnsupportedOperationException
(
"根节点不能删。"
);
}
if
(
productItem
.
getPid
()
==
currentItem
.
getId
())
{
currentItem
.
removeChild
(
productItem
);
return
currentItem
;
}
delChild
(
productItem
,
currentItem
);
return
currentItem
;
}
private
void
delChild
(
ProductItem
productItem
,
ProductItem
currentItem
)
{
for
(
ProductItem
item
:
currentItem
.
getChild
())
{
if
(
item
.
getId
()
==
productItem
.
getPid
())
{
item
.
removeChild
(
productItem
);
break
;
}
else
{
delChild
(
productItem
,
item
);
}
}
}
}
src/main/java/com/study/design/items/visitor/ItemVisitor.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.items.visitor
;
import
com.study.design.items.node.ProductItem
;
public
interface
ItemVisitor
<
T
>
{
T
visitor
(
ProductItem
productItem
);
}
src/main/java/com/study/design/order/OrderStateListener.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.order
;
import
com.study.design.order.pojo.Order
;
import
com.study.design.order.pojo.OrderState
;
import
com.study.design.order.pojo.OrderStateChangeAction
;
import
org.springframework.messaging.Message
;
import
org.springframework.statemachine.annotation.OnTransition
;
import
org.springframework.statemachine.annotation.WithStateMachine
;
import
org.springframework.stereotype.Component
;
// 监听器是监听到 action 后进行状态的一个变更。
@Component
(
"orderStateListener"
)
@WithStateMachine
(
name
=
"orderStateMachine"
)
public
class
OrderStateListener
{
@OnTransition
(
source
=
"ORDER_WAIT_PAY"
,
target
=
"ORDER_WAIT_SEND"
)
public
boolean
payToSend
(
Message
<
OrderStateChangeAction
>
message
){
Order
order
=
(
Order
)
message
.
getHeaders
().
get
(
"order"
);
order
.
setOrderState
(
OrderState
.
ORDER_WAIT_SEND
);
return
true
;
}
@OnTransition
(
source
=
"ORDER_WAIT_SEND"
,
target
=
"ORDER_WAIT_RECEIVE"
)
public
boolean
sendToReceive
(
Message
<
OrderStateChangeAction
>
message
){
Order
order
=
(
Order
)
message
.
getHeaders
().
get
(
"order"
);
order
.
setOrderState
(
OrderState
.
ORDER_WAIT_RECEIVE
);
return
true
;
}
@OnTransition
(
source
=
"ORDER_WAIT_RECEIVE"
,
target
=
"ORDER_FINISH"
)
public
boolean
receiveToFinish
(
Message
<
OrderStateChangeAction
>
message
){
Order
order
=
(
Order
)
message
.
getHeaders
().
get
(
"order"
);
order
.
setOrderState
(
OrderState
.
ORDER_FINISH
);
return
true
;
}
}
src/main/java/com/study/design/order/config/OrderStateMachineConfig.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.order.config
;
import
com.study.design.order.pojo.Order
;
import
com.study.design.order.pojo.OrderState
;
import
com.study.design.order.pojo.OrderStateChangeAction
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.statemachine.StateMachineContext
;
import
org.springframework.statemachine.StateMachinePersist
;
import
org.springframework.statemachine.config.EnableStateMachine
;
import
org.springframework.statemachine.config.StateMachineConfigurerAdapter
;
import
org.springframework.statemachine.config.builders.StateMachineStateConfigurer
;
import
org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer
;
import
org.springframework.statemachine.persist.DefaultStateMachinePersister
;
import
org.springframework.statemachine.support.DefaultStateMachineContext
;
import
java.util.EnumSet
;
@Configuration
@EnableStateMachine
(
name
=
"orderStateMachine"
)
public
class
OrderStateMachineConfig
extends
StateMachineConfigurerAdapter
<
OrderState
,
OrderStateChangeAction
>
{
public
void
configure
(
StateMachineStateConfigurer
<
OrderState
,
OrderStateChangeAction
>
states
)
throws
Exception
{
states
.
withStates
().
initial
(
OrderState
.
ORDER_WAIT_PAY
)
.
states
(
EnumSet
.
allOf
(
OrderState
.
class
));
}
public
void
configure
(
StateMachineTransitionConfigurer
<
OrderState
,
OrderStateChangeAction
>
transitions
)
throws
Exception
{
transitions
.
withExternal
().
source
(
OrderState
.
ORDER_WAIT_PAY
)
.
target
(
OrderState
.
ORDER_WAIT_SEND
)
.
event
(
OrderStateChangeAction
.
PAY_ORDER
)
.
and
()
.
withExternal
().
source
(
OrderState
.
ORDER_WAIT_SEND
)
.
target
(
OrderState
.
ORDER_WAIT_RECEIVE
)
.
event
(
OrderStateChangeAction
.
SEND_ORDER
)
.
and
()
.
withExternal
().
source
(
OrderState
.
ORDER_WAIT_RECEIVE
)
.
target
(
OrderState
.
ORDER_FINISH
)
.
event
(
OrderStateChangeAction
.
RECEIVE_ORDER
);
}
// 配置状态机持久化
@Bean
public
DefaultStateMachinePersister
machinePersister
()
{
return
new
DefaultStateMachinePersister
<>(
new
StateMachinePersist
<
Object
,
Object
,
Order
>()
{
@Override
public
void
write
(
StateMachineContext
<
Object
,
Object
>
stateMachineContext
,
Order
order
)
throws
Exception
{
//持久化操作。可以通过任何形式进行持久化。redis 、 mongodb、mysql,ecache
}
@Override
public
StateMachineContext
<
Object
,
Object
>
read
(
Order
order
)
throws
Exception
{
// 本来是应该从持久化组件里进行读取的。但是没做持久化
return
new
DefaultStateMachineContext
(
order
.
getOrderState
(),
null
,
null
,
null
);
}
});
}
}
src/main/java/com/study/design/order/pojo/Order.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.order.pojo
;
//状态转化的一个控制机。状态机:初始化状态;配置我们的所有状态之间的转化关系;
//一些持久化的工作(redis)。
public
class
Order
{
private
Integer
orderId
;
private
OrderState
orderState
;
//订单状态
public
Integer
getOrderId
()
{
return
orderId
;
}
public
void
setOrderId
(
Integer
orderId
)
{
this
.
orderId
=
orderId
;
}
public
OrderState
getOrderState
()
{
return
orderState
;
}
public
void
setOrderState
(
OrderState
orderState
)
{
this
.
orderState
=
orderState
;
}
}
src/main/java/com/study/design/order/pojo/OrderState.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.order.pojo
;
public
enum
OrderState
{
ORDER_WAIT_PAY
,
// 待支付
ORDER_WAIT_SEND
,
// 待发货
ORDER_WAIT_RECEIVE
,
// 待收货
ORDER_FINISH
;
// 完成订单
}
src/main/java/com/study/design/order/pojo/OrderStateChangeAction.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.order.pojo
;
public
enum
OrderStateChangeAction
{
PAY_ORDER
,
// 支付操作
SEND_ORDER
,
// 发货操作
RECEIVE_ORDER
;
// 收货操作
}
src/main/java/com/study/design/pay/additionalDecorator/AbstractAddFuncDecorator.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.pay.additionalDecorator
;
import
com.study.design.pay.pojo.PayBody
;
import
com.study.design.pay.strategyContext.AbstractPayContext
;
public
abstract
class
AbstractAddFuncDecorator
extends
AbstractPayContext
{
// 这是我们的装饰器类。专门干装修的。 专门添加新功能的(平台币,红包)
// 装饰的是谁啊? 我作为一个称职的装饰器,我必须得知道装饰的是谁,不然我咋干活儿啊。
private
AbstractPayContext
abstractPayContext
=
null
;
public
AbstractAddFuncDecorator
(
AbstractPayContext
abstractPayContext
)
{
this
.
abstractPayContext
=
abstractPayContext
;
}
// 开始干活儿
//1. 老活儿。 支付。但是我又不能修改支付代码,也不能修改支付逻辑。
@Override
public
Boolean
execute
(
PayBody
payBody
)
{
return
abstractPayContext
.
execute
(
payBody
);
}
//2. 老活儿不合适,没你装饰器照样能execute。 新活儿:平台币,红包)
public
abstract
void
additionalFunction
(
PayBody
payBody
);
}
src/main/java/com/study/design/pay/additionalDecorator/AddFuncDecorator.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.pay.additionalDecorator
;
import
com.study.design.pay.pojo.PayBody
;
import
com.study.design.pay.strategyContext.AbstractPayContext
;
/**
* abstractPayContext 不是共享的,因为有的小伙伴选择 zfb 支付,有的小伙伴选择wx支付,等等。。。
*
* @author : qinyingjie
* @version : 2.2.0
* @date : 2022/9/27 02:20
*/
public
class
AddFuncDecorator
extends
AbstractAddFuncDecorator
{
public
AddFuncDecorator
(
AbstractPayContext
abstractPayContext
)
{
super
(
abstractPayContext
);
}
/**
* 新活儿
*
* @param payBody
*/
@Override
public
void
additionalFunction
(
PayBody
payBody
)
{
// 共享的,跟支付策略没有任何关系
String
product
=
payBody
.
getProduct
();
// 从db里边获取 product的详细信息。
// 从配置中心(redis缓存)里获取产品的更新策略。
// 根据策略更新用户平台币 或(和) 发放红包。
System
.
out
.
println
(
"更新平台币成功,发送红包到用户优惠券模块成功。"
);
}
@Override
public
Boolean
execute
(
PayBody
payBody
)
{
// 算共享的。共享的调用逻辑
Boolean
result
=
super
.
execute
(
payBody
);
//老活儿
this
.
additionalFunction
(
payBody
);
// 新活儿. 新活儿的各种重试,失败补偿
return
result
;
}
}
src/main/java/com/study/design/pay/facade/StrategyFacade.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.pay.facade
;
import
com.study.design.pay.additionalDecorator.AddFuncDecorator
;
import
com.study.design.pay.factory.AddFuncFactory
;
import
com.study.design.pay.pojo.PayBody
;
import
com.study.design.pay.strategy.PayStrategy
;
import
com.study.design.pay.strategyContext.PayContext
;
import
com.study.design.pay.strategyEnum.StrategyEnum
;
import
com.study.design.pay.factory.StrategyFactory
;
// 最终我们只暴露我们的门面,对于里边的这些所有的工厂。策略啊。策略枚举啊,统统不暴露。
// 门面就是我们的超强封装。
public
class
StrategyFacade
{
// 定义一个map,将对应关系提前初始化好。
// 双十一的时候,有大量的用户进行下单(千万级),就会造成千万级的pay接口的调用。
// 很可惜,这部分代码里边有两个 new 关键字(new PayContext(payStrategy) 和 new AddFuncDecorator)。
// 如果瞬时见。有几十万的并发进来,那么会创建几十万个 context对象和 addFunc对象,造成 年轻代的eden区的频繁对象创建
// 虽然说调用完就进行了对象的垃圾收集,但是这么多的访问对象进来会造成,minorgc。
// 1. 单例模式吗?PayContext创建是基于payStrategy,不止一种paycontext啊,用单例不行呀。 AddFuncDecorator 是基于PayContext
// 创建的,PayContext 不止一种,AddFuncDecorator 也不止一种。
// 2. 享元模式。享元模式是单例模式的一种思想升级。单例模式,针对的是同一种对象,没有任何不同的细节。而享元模式,针对多个对象。
// 多个对象:同一种class,但是里边的属性有些许不同。PayContext是同一种对象吧?是的; PayContext 是不是有细节上的不同呢?是的,
// payStrategy不同; 那么我们是否可以知道这个PayContext的种类数量呢?是的,目前有三种。 享元模式能够对这可控数量的有不同细节的
//同一种class对象进行共享,保证我们的程序不频繁的创建对象。
public
static
Boolean
pay
(
PayBody
payBody
)
{
//获取我们的 策略枚举
StrategyEnum
strategyEnum
=
getStrategyEnum
(
payBody
.
getType
());
if
(
strategyEnum
==
null
)
{
return
false
;
}
//获取我们的策略对象
PayStrategy
payStrategy
=
StrategyFactory
.
getPayStrategy
(
strategyEnum
);
//生成我们的策略上下文
PayContext
context
=
new
PayContext
(
payStrategy
);
// TO DO
// 装饰一下 context,。立马多了一个功能
// 我看这行代码啊,就不顺眼。代理模式搞他。
AddFuncDecorator
addFuncDecorator
=
(
AddFuncDecorator
)
AddFuncFactory
.
getAddFunc
(
context
);
//进行扣款
return
addFuncDecorator
.
execute
(
payBody
);
}
private
static
StrategyEnum
getStrategyEnum
(
int
type
)
{
switch
(
type
)
{
case
0
:
return
StrategyEnum
.
ZfbPayStrategy
;
case
1
:
return
StrategyEnum
.
WcPayStrategy
;
case
2
:
return
StrategyEnum
.
BkPayStrategy
;
default
:
return
null
;
}
}
}
src/main/java/com/study/design/pay/factory/AddFuncFactory.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.pay.factory
;
import
com.study.design.pay.additionalDecorator.AbstractAddFuncDecorator
;
import
com.study.design.pay.additionalDecorator.AddFuncDecorator
;
import
com.study.design.pay.strategyContext.PayContext
;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
public
class
AddFuncFactory
{
// 工厂的目的是生产 AddFuncDecorator; 生产几个啊? 多个:享元
// key 应该是能够和 AbstractAddFuncDecorator 做成对应的东西。
// 这个map最多保存是三个对象。
public
final
static
Map
<
PayContext
,
AbstractAddFuncDecorator
>
maps
=
new
ConcurrentHashMap
<>();
public
static
AbstractAddFuncDecorator
getAddFunc
(
PayContext
payContext
)
{
if
(
maps
.
get
(
payContext
)
==
null
)
{
AddFuncDecorator
addFuncDecorator
=
new
AddFuncDecorator
(
payContext
);
maps
.
put
(
payContext
,
addFuncDecorator
);
}
return
maps
.
get
(
payContext
);
}
}
src/main/java/com/study/design/pay/factory/StrategyFactory.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.pay.factory
;
import
com.study.design.pay.strategy.PayStrategy
;
import
com.study.design.pay.strategyEnum.StrategyEnum
;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
/**
* 我们的工厂类依靠我们的策略枚举返回策略类
* 我们以后永远不需要修改我们的Factory。他是一个无状态的
*
* @author : qinyingjie
* @version : 2.2.0
* @date : 2022/9/27 02:21
*/
public
class
StrategyFactory
{
//那个时候我们 引出他是为了讲解 单例模式,其实那个时候我们已经利用了单例模式
//思想升级之后的享元,模式了。
private
static
final
Map
<
String
,
PayStrategy
>
strategyMaps
=
new
ConcurrentHashMap
();
public
static
PayStrategy
getPayStrategy
(
StrategyEnum
strategyEnum
)
{
PayStrategy
payStrategy
=
strategyMaps
.
get
(
strategyEnum
.
getValue
());
if
(
payStrategy
==
null
)
{
try
{
// 每次调用都需要进行一次反射。优化调整。
payStrategy
=
(
PayStrategy
)
Class
.
forName
(
strategyEnum
.
getValue
()).
newInstance
();
strategyMaps
.
put
(
strategyEnum
.
getValue
(),
payStrategy
);
}
catch
(
Exception
e
)
{
//异常
}
}
return
payStrategy
;
}
// 工厂模式的变种比较多。虽然这里边我写了一个 有静态方法的 工厂类,但是要与我们平时
//写的 utils 类进行区分,utils 是以功能(生成uuid,日期转化)为导向的工具类。
// 而 我写的factory类,他是以产出(一类行为类:策略)为导向的
}
src/main/java/com/study/design/pay/pojo/PayBody.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.pay.pojo
;
public
class
PayBody
{
private
String
account
;
private
int
type
;
private
String
product
;
private
int
amount
;
public
String
getAccount
()
{
return
account
;
}
public
void
setAccount
(
String
account
)
{
this
.
account
=
account
;
}
public
int
getType
()
{
return
type
;
}
public
void
setType
(
int
type
)
{
this
.
type
=
type
;
}
public
String
getProduct
()
{
return
product
;
}
public
void
setProduct
(
String
product
)
{
this
.
product
=
product
;
}
public
int
getAmount
()
{
return
amount
;
}
public
void
setAmount
(
int
amount
)
{
this
.
amount
=
amount
;
}
}
src/main/java/com/study/design/pay/proxy/ContextProxy.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.pay.proxy
;
import
com.study.design.pay.pojo.PayBody
;
import
com.study.design.pay.strategyContext.AbstractPayContext
;
public
class
ContextProxy
extends
AbstractPayContext
{
private
AbstractPayContext
abstractPayContext
=
null
;
public
ContextProxy
(
AbstractPayContext
abstractPayContext
)
{
this
.
abstractPayContext
=
abstractPayContext
;
}
@Override
public
Boolean
execute
(
PayBody
payBody
)
{
return
null
;
}
}
src/main/java/com/study/design/pay/strategy/BkPayStrategy.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.pay.strategy
;
import
com.study.design.pay.pojo.PayBody
;
public
class
BkPayStrategy
implements
PayStrategy
{
@Override
public
Boolean
pay
(
PayBody
payBody
)
{
// 支付细节省略
return
true
;
}
}
src/main/java/com/study/design/pay/strategy/PayStrategy.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.pay.strategy
;
import
com.study.design.pay.pojo.PayBody
;
/**
* // 增加一个付款方式的话,需要写一个 strategy的子类实现类,类似Wc。
* // 枚举类增加一个枚举,就一行代码。
* // 门面类 中枚举获取的修改。
* // 扩展性良好,而且不影响 调用端。我们的任何改动,不需要让调用端知道。
*
* @author : qinyingjie
* @version : 2.2.0
* @date : 2022/9/27 02:22
*/
public
interface
PayStrategy
{
Boolean
pay
(
PayBody
payBody
);
// 之所以使用interface,是因为我们的所有的策略接口下的方法都是需要复写的,
// 没有公共的、可重用的方法。
//abstract class 他能够有自己的 抽象方法(需要子类复写的)
// abstract class 他也能够有自己的可执行方法(普通的方法,不抽象的)
}
src/main/java/com/study/design/pay/strategy/WcPayStrategy.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.pay.strategy
;
import
com.study.design.pay.pojo.PayBody
;
public
class
WcPayStrategy
implements
PayStrategy
{
@Override
public
Boolean
pay
(
PayBody
payBody
)
{
// 支付细节省略
return
true
;
}
}
src/main/java/com/study/design/pay/strategy/ZfbPayStrategy.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.pay.strategy
;
import
com.study.design.pay.pojo.PayBody
;
public
class
ZfbPayStrategy
implements
PayStrategy
{
@Override
public
Boolean
pay
(
PayBody
payBody
)
{
//支付细节省略
return
true
;
}
}
src/main/java/com/study/design/pay/strategyContext/AbstractPayContext.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.pay.strategyContext
;
import
com.study.design.pay.pojo.PayBody
;
public
abstract
class
AbstractPayContext
{
public
abstract
Boolean
execute
(
PayBody
payBody
);
}
src/main/java/com/study/design/pay/strategyContext/PayContext.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.pay.strategyContext
;
import
com.study.design.pay.strategy.PayStrategy
;
import
com.study.design.pay.pojo.PayBody
;
/**
* // 动态地给一个对象添加一些额外的职责. 就得在根儿上添加。
* //PayContext 就是我们的被装饰者,因为我们想给payContext添加额外功能:平台币更新和红包
* // 所以我们选择使用装饰者模式。被装饰者必须要有 接口或者抽象类。也就是类图中的
*
* @author : qinyingjie
* @version : 2.2.0
* @date : 2022/9/27 02:22
*/
public
class
PayContext
extends
AbstractPayContext
{
private
PayStrategy
payStrategy
;
public
PayContext
(
PayStrategy
payStrategy
)
{
this
.
payStrategy
=
payStrategy
;
}
@Override
public
Boolean
execute
(
PayBody
payBody
)
{
return
this
.
payStrategy
.
pay
(
payBody
);
}
}
src/main/java/com/study/design/pay/strategyEnum/StrategyEnum.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.pay.strategyEnum
;
public
enum
StrategyEnum
{
ZfbPayStrategy
(
"com.study.design.pay.strategy.ZfbPayStrategy"
),
WcPayStrategy
(
"com.study.design.pay.strategy.WcPayStrategy"
),
BkPayStrategy
(
"com.study.design.pay.strategy.BkPayStrategy"
);
String
value
=
""
;
StrategyEnum
(
String
value
)
{
this
.
value
=
value
;
}
public
String
getValue
()
{
return
this
.
value
;
}
}
src/main/java/com/study/design/pojo/TicketParam.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.pojo
;
public
class
TicketParam
{
/**
* 真实的项目里,我们的account是set到用户的请求头里的 ,header里。过我们的网管的时候就已经记录了
*/
private
String
account
;
private
String
title
;
private
String
bankInfo
;
private
String
productId
;
public
String
getAccount
()
{
return
account
;
}
public
void
setAccount
(
String
account
)
{
this
.
account
=
account
;
}
public
String
getTitle
()
{
return
title
;
}
public
void
setTitle
(
String
title
)
{
this
.
title
=
title
;
}
public
String
getBankInfo
()
{
return
bankInfo
;
}
public
void
setBankInfo
(
String
bankInfo
)
{
this
.
bankInfo
=
bankInfo
;
}
public
String
getProductId
()
{
return
productId
;
}
public
void
setProductId
(
String
productId
)
{
this
.
productId
=
productId
;
}
}
src/main/java/com/study/design/pojo/UserInfo.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.pojo
;
import
java.util.List
;
public
class
UserInfo
{
private
String
username
;
private
String
city
;
private
List
<
String
>
buyProducts
;
private
boolean
isNewUser
;
public
String
getUsername
()
{
return
username
;
}
public
void
setUsername
(
String
username
)
{
this
.
username
=
username
;
}
public
String
getCity
()
{
return
city
;
}
public
void
setCity
(
String
city
)
{
this
.
city
=
city
;
}
public
List
<
String
>
getBuyProducts
()
{
return
buyProducts
;
}
public
void
setBuyProducts
(
List
<
String
>
buyProducts
)
{
this
.
buyProducts
=
buyProducts
;
}
public
boolean
isNewUser
()
{
return
isNewUser
;
}
public
void
setNewUser
(
boolean
newUser
)
{
isNewUser
=
newUser
;
}
}
src/main/java/com/study/design/service/EsService.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.service
;
import
com.study.design.esquery.EsQueryProcessor
;
import
com.study.design.order.pojo.Order
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Component
;
import
org.springframework.stereotype.Service
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.stream.Stream
;
@Service
public
class
EsService
{
@Autowired
private
EsQueryProcessor
esQueryProcessor
;
public
Boolean
query
(
String
query
,
Long
fetchSize
)
{
Stream
<
Map
<
String
,
Object
>>
mapStream
=
esQueryProcessor
.
scrollEsStream
(
query
,
fetchSize
);
mapStream
.
forEach
(
x
->
System
.
out
.
println
(
x
));
return
true
;
}
}
src/main/java/com/study/design/service/ItemService.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.service
;
import
com.study.design.MockDb
;
import
com.study.design.items.node.ProductItem
;
import
com.study.design.items.visitor.AddItemVisitor
;
import
com.study.design.items.visitor.DelItemVisitor
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
@Service
public
class
ItemService
{
@Autowired
private
DelItemVisitor
delItemVisitor
;
@Autowired
private
AddItemVisitor
addItemVisitor
;
/**
* 这部分只有初始化的时候获取一次 或者 直接预热到缓存中
*/
public
ProductItem
getItem
()
{
System
.
out
.
println
(
"从DB 获取所有的目录"
);
System
.
out
.
println
(
"将数据组装为 ProductItem"
);
System
.
out
.
println
(
"将组装好的 ProductItem 放入缓存中,永不过期 "
);
return
MockDb
.
ProductItem
;
}
public
ProductItem
delItem
(
ProductItem
productItem
)
{
ProductItem
item
=
delItemVisitor
.
visitor
(
productItem
);
MockDb
.
ProductItem
=
item
;
System
.
out
.
println
(
"update db"
);
return
item
;
}
public
ProductItem
addItem
(
ProductItem
productItem
)
{
ProductItem
item
=
addItemVisitor
.
visitor
(
productItem
);
MockDb
.
ProductItem
=
item
;
System
.
out
.
println
(
"update db"
);
return
item
;
}
}
src/main/java/com/study/design/service/OrderService.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.service
;
import
com.study.design.auditlog.OrderLogProcessor
;
import
com.study.design.auditlog.PayLogProcessor
;
import
com.study.design.order.pojo.Order
;
import
com.study.design.order.pojo.OrderState
;
import
com.study.design.order.pojo.OrderStateChangeAction
;
import
com.study.design.pay.facade.StrategyFacade
;
import
com.study.design.pay.pojo.PayBody
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.messaging.Message
;
import
org.springframework.messaging.support.MessageBuilder
;
import
org.springframework.statemachine.StateMachine
;
import
org.springframework.statemachine.persist.StateMachinePersister
;
import
org.springframework.stereotype.Service
;
import
java.util.ArrayList
;
import
java.util.List
;
@Service
public
class
OrderService
{
@Autowired
private
StateMachine
<
OrderState
,
OrderStateChangeAction
>
orderStateMachine
;
@Autowired
private
StateMachinePersister
<
OrderState
,
OrderStateChangeAction
,
Order
>
stateMachinePersister
;
@Autowired
private
PayLogProcessor
payLogProcessor
;
@Autowired
private
OrderLogProcessor
orderLogProcessor
;
/**
* 模拟一个存储
*/
private
final
List
<
Object
>
orders
=
new
ArrayList
<>();
public
Order
createOrder
(
Integer
oid
)
{
Order
order
=
new
Order
();
order
.
setOrderState
(
OrderState
.
ORDER_WAIT_PAY
);
order
.
setOrderId
(
oid
);
// 创建的order是不是得入库啊?如果不入库,下次访问的时候,是不是找不到了啊。
orders
.
add
(
order
);
//模拟存储到 db
orderLogProcessor
.
processAuditLog
(
"acccount"
,
"createOrder"
,
oid
.
toString
());
return
order
;
}
// 将来我们删除或者增加或者修改任何关于付款的模块,无需改动service。
//不会对调用层产生任何代码的改动。
// 调用层使用我们的pay 模块,无需关系实现的逻辑,只需要将入参传给我们的pay模块即可。
public
Order
pay
(
PayBody
payBody
)
{
// 书写我们的付款逻辑
boolean
flag
=
false
;
flag
=
StrategyFacade
.
pay
(
payBody
);
if
(
flag
)
{
Order
order
=
(
Order
)
orders
.
get
(
0
);
// 模拟查询db代码
payLogProcessor
.
processAuditLog
(
payBody
.
getAccount
(),
"pay"
,
order
.
getOrderId
().
toString
());
Message
message
=
MessageBuilder
.
withPayload
(
OrderStateChangeAction
.
PAY_ORDER
).
setHeader
(
"order"
,
order
).
build
();
//发送消息,发送给谁?和状态机有没有关系啊? 有
if
(
changeStateAction
(
message
,
order
))
{
return
order
;
}
//如果是 true,我们要保存到db
saveToDb
(
payBody
);
}
return
null
;
}
private
void
saveToDb
(
PayBody
payBody
)
{
}
public
Order
send
(
Integer
oid
)
{
Order
order
=
(
Order
)
orders
.
get
(
0
);
// 模拟查询db代码
Message
message
=
MessageBuilder
.
withPayload
(
OrderStateChangeAction
.
SEND_ORDER
).
setHeader
(
"order"
,
order
).
build
();
if
(
changeStateAction
(
message
,
order
))
{
return
order
;
}
return
null
;
}
public
Order
receive
(
Integer
oid
)
{
Order
order
=
(
Order
)
orders
.
get
(
0
);
// 模拟查询db代码
Message
message
=
MessageBuilder
.
withPayload
(
OrderStateChangeAction
.
RECEIVE_ORDER
).
setHeader
(
"order"
,
order
).
build
();
if
(
changeStateAction
(
message
,
order
))
{
return
order
;
}
return
null
;
}
private
boolean
changeStateAction
(
Message
<
OrderStateChangeAction
>
message
,
Order
order
)
{
try
{
orderStateMachine
.
start
();
stateMachinePersister
.
restore
(
orderStateMachine
,
order
);
// 待议
boolean
res
=
orderStateMachine
.
sendEvent
(
message
);
stateMachinePersister
.
persist
(
orderStateMachine
,
order
);
// 持久
return
res
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
finally
{
orderStateMachine
.
stop
();
}
return
false
;
}
}
src/main/java/com/study/design/service/UserService.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.service
;
import
com.study.design.handler.SuggestRequirementHandlerProcess
;
import
com.study.design.pojo.TicketParam
;
import
com.study.design.pojo.UserInfo
;
import
com.study.design.ticket.builder.CompanyTicketBuilder
;
import
com.study.design.ticket.builder.PersonalTicketBuilder
;
import
com.study.design.ticket.builder.TicketBuilder
;
import
login.implementor.LoginFunc
;
import
login.implementor.WbLoginFunc
;
import
login.implementor.abstractlogin.AbstractLoginProcessor
;
import
login.implementor.abstractlogin.ThirdPartLogin
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
java.util.ArrayList
;
import
java.util.List
;
@Service
public
class
UserService
{
@Autowired
private
SuggestRequirementHandlerProcess
suggestRequirementHandlerProcess
;
public
List
<
String
>
suggestRequirement
(
String
username
)
{
//获取用户信息。因为用户已经登录了,那么user的信息是保存在我们的缓存里的。
UserInfo
userInfo
=
getUserInfo
(
username
);
List
<
String
>
results
=
new
ArrayList
<>();
// 你可以发现,调用方无需关心任何 handler。完全对其屏蔽的。而且是
// 完全解耦
suggestRequirementHandlerProcess
.
process
(
userInfo
,
results
);
return
results
;
}
//因为这部分是需要查询 缓存(如果缓存没有,需要查库)不应该写到 service层,但是为了代码书写简便
//这部分我模拟在service 层。
private
UserInfo
getUserInfo
(
String
username
)
{
return
new
UserInfo
();
}
public
Object
getTicket
(
TicketParam
ticketParam
)
{
TicketBuilder
builder
=
null
;
String
bankInfo
=
null
;
if
(
ticketParam
.
getBankInfo
()
!=
null
)
{
bankInfo
=
"from 3rd party interface check."
;
builder
=
new
CompanyTicketBuilder
();
}
else
{
builder
=
new
PersonalTicketBuilder
();
}
builder
.
setParam
(
ticketParam
.
getAccount
(),
ticketParam
.
getTitle
());
String
content
=
"from config center"
;
String
product
=
"from db"
;
builder
.
setContent
(
content
);
builder
.
setProduct
(
product
);
builder
.
setBankInfo
(
bankInfo
);
// 详细的逻辑细节控制以及从配置中心或者是db中获取的逻辑步骤就是简单的 crud,自己明白即可
return
builder
.
buildTicket
();
}
public
Boolean
login
(
String
name
,
String
pwd
,
String
type
)
{
// 这部分我就不进行封装了,直接在 service里做了。小伙伴可以自行实现封装,类似享元。
// 这部分是桥接模式的实现。
// if(type.equals("wb")) {
// LoginFunc func = new WbLoginFunc();
// AbstractLoginProcessor processor = new ThirdPartLogin(func);
// return processor.loginExecute(name, pwd, type);
// }
return
true
;
}
}
src/main/java/com/study/design/ticket/TicketConstant.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.ticket
;
import
com.study.design.ticket.pojo.CompanyTicket
;
import
com.study.design.ticket.pojo.PersonalTicket
;
public
class
TicketConstant
{
// 保存只具有公共属性的对象,供clone使用。
public
static
PersonalTicket
personalTicket
=
new
PersonalTicket
();
public
static
CompanyTicket
companyTicket
=
new
CompanyTicket
();
static
{
personalTicket
.
setType
(
"type"
);
personalTicket
.
setFooter
(
"footer"
);
companyTicket
.
setType
(
"type"
);
companyTicket
.
setFooter
(
"footer"
);
}
}
src/main/java/com/study/design/ticket/builder/CompanyTicketBuilder.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.ticket.builder
;
import
com.study.design.ticket.TicketConstant
;
import
com.study.design.ticket.pojo.CompanyTicket
;
public
class
CompanyTicketBuilder
extends
TicketBuilder
<
CompanyTicket
>
{
/**
* new 关键字
*/
private
CompanyTicket
companyTicket
=
TicketConstant
.
companyTicket
.
clone
();
@Override
public
void
setBankInfo
(
String
bankInfo
)
{
companyTicket
.
setBankInfo
(
bankInfo
);
}
@Override
public
void
setParam
(
String
account
,
String
title
)
{
companyTicket
.
setTitle
(
title
);
companyTicket
.
setAccount
(
account
);
}
@Override
public
void
setContent
(
String
content
)
{
companyTicket
.
setContent
(
content
);
}
@Override
public
void
setProduct
(
String
product
)
{
companyTicket
.
setProduct
(
product
);
}
@Override
public
CompanyTicket
buildTicket
()
{
return
companyTicket
;
}
}
src/main/java/com/study/design/ticket/builder/PersonalTicketBuilder.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.ticket.builder
;
import
com.study.design.ticket.TicketConstant
;
import
com.study.design.ticket.pojo.PersonalTicket
;
public
class
PersonalTicketBuilder
extends
TicketBuilder
<
PersonalTicket
>
{
/**
* new 关键字 改成clone的形式,只clone我们的
* <p>
* 不可变部分。对于可变部分和自定义用户提交部分,不进行clone
*/
private
PersonalTicket
personalTicket
=
TicketConstant
.
personalTicket
.
clone
();
@Override
public
void
setParam
(
String
account
,
String
title
)
{
personalTicket
.
setTitle
(
title
);
personalTicket
.
setAccount
(
account
);
}
@Override
public
void
setContent
(
String
content
)
{
personalTicket
.
setContent
(
content
);
}
@Override
public
void
setProduct
(
String
product
)
{
personalTicket
.
setProduct
(
product
);
}
@Override
public
PersonalTicket
buildTicket
()
{
return
personalTicket
;
}
}
src/main/java/com/study/design/ticket/builder/TicketBuilder.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.ticket.builder
;
public
abstract
class
TicketBuilder
<
T
>
{
public
abstract
void
setParam
(
String
account
,
String
title
);
public
abstract
void
setContent
(
String
content
);
// 配置中心 或 DB 或缓存
public
abstract
void
setProduct
(
String
product
);
// db
public
void
setBankInfo
(
String
bankInfo
){};
//需要校验的,校验通过才能设置
public
abstract
T
buildTicket
();
}
src/main/java/com/study/design/ticket/pojo/CompanyTicket.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.ticket.pojo
;
public
class
CompanyTicket
implements
Cloneable
{
private
String
type
;
private
String
footer
;
private
String
content
;
//配置中心 或者 DB里边获取。(缓存里获取,只不过如果万一DB 或配置中心有修改,需要同时更新缓存)
private
String
product
;
//大部分情况db里获取(缓存里是有一些热门产品的)
private
String
bankInfo
;
//校验我们的银行卡信息(通过我们的第三方银行相关接口进行的校验)
private
String
account
;
private
String
title
;
public
String
getFooter
()
{
return
footer
;
}
public
void
setFooter
(
String
footer
)
{
this
.
footer
=
footer
;
}
public
String
getTitle
()
{
return
title
;
}
public
void
setTitle
(
String
title
)
{
this
.
title
=
title
;
}
public
String
getType
()
{
return
type
;
}
public
void
setType
(
String
type
)
{
this
.
type
=
type
;
}
public
String
getAccount
()
{
return
account
;
}
public
void
setAccount
(
String
account
)
{
this
.
account
=
account
;
}
public
String
getContent
()
{
return
content
;
}
public
void
setContent
(
String
content
)
{
this
.
content
=
content
;
}
public
String
getProduct
()
{
return
product
;
}
public
void
setProduct
(
String
product
)
{
this
.
product
=
product
;
}
public
String
getBankInfo
()
{
return
bankInfo
;
}
public
void
setBankInfo
(
String
bankInfo
)
{
this
.
bankInfo
=
bankInfo
;
}
@Override
public
CompanyTicket
clone
()
{
CompanyTicket
companyTicket
=
null
;
try
{
companyTicket
=
(
CompanyTicket
)
super
.
clone
();
}
catch
(
CloneNotSupportedException
e
)
{
e
.
printStackTrace
();
}
return
companyTicket
;
}
}
src/main/java/com/study/design/ticket/pojo/PersonalTicket.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design.ticket.pojo
;
public
class
PersonalTicket
implements
Cloneable
{
private
String
type
;
private
String
footer
;
private
String
content
;
//配置中心 或者 DB里边获取。(缓存里获取,只不过如果万一DB 或配置中心有修改,需要同时更新缓存)
private
String
product
;
//大部分情况db里获取(缓存里是有一些热门产品的)
private
String
account
;
// 接口入参获取
private
String
title
;
// 接口入参获取
public
String
getFooter
()
{
return
footer
;
}
public
void
setFooter
(
String
footer
)
{
this
.
footer
=
footer
;
}
public
String
getTitle
()
{
return
title
;
}
public
void
setTitle
(
String
title
)
{
this
.
title
=
title
;
}
public
String
getType
()
{
return
type
;
}
public
void
setType
(
String
type
)
{
this
.
type
=
type
;
}
public
String
getAccount
()
{
return
account
;
}
public
void
setAccount
(
String
account
)
{
this
.
account
=
account
;
}
public
String
getContent
()
{
return
content
;
}
public
void
setContent
(
String
content
)
{
this
.
content
=
content
;
}
public
String
getProduct
()
{
return
product
;
}
public
void
setProduct
(
String
product
)
{
this
.
product
=
product
;
}
@Override
public
PersonalTicket
clone
()
{
PersonalTicket
personalTicket
=
null
;
try
{
personalTicket
=
(
PersonalTicket
)
super
.
clone
();
}
catch
(
CloneNotSupportedException
e
)
{
e
.
printStackTrace
();
}
return
personalTicket
;
}
}
src/main/java/login/implementor/LoginFunc.java
0 → 100644
浏览文件 @
5d62c194
package
login.implementor
;
public
interface
LoginFunc
{
public
boolean
login
(
String
name
,
String
pwd
,
String
type
);
}
src/main/java/login/implementor/WbLoginFunc.java
0 → 100644
浏览文件 @
5d62c194
package
login.implementor
;
public
class
WbLoginFunc
implements
LoginFunc
{
@Override
public
boolean
login
(
String
name
,
String
pwd
,
String
type
)
{
// 进行第三方账号的校验流程。
System
.
out
.
println
(
"Wb 验证通过,可以登录。"
);
return
true
;
}
}
src/main/java/login/implementor/ZfbLoginFunc.java
0 → 100644
浏览文件 @
5d62c194
package
login.implementor
;
public
class
ZfbLoginFunc
implements
LoginFunc
{
@Override
public
boolean
login
(
String
name
,
String
pwd
,
String
type
)
{
// 进行第三方账号的校验流程。
System
.
out
.
println
(
"Zfb 验证通过,可以登录。"
);
return
true
;
}
}
src/main/java/login/implementor/abstractlogin/AbstractLoginProcessor.java
0 → 100644
浏览文件 @
5d62c194
package
login.implementor.abstractlogin
;
import
login.implementor.LoginFunc
;
public
abstract
class
AbstractLoginProcessor
{
protected
LoginFunc
loginFunc
;
public
AbstractLoginProcessor
(
LoginFunc
loginFunc
)
{
this
.
loginFunc
=
loginFunc
;
}
public
abstract
boolean
loginExecute
(
String
name
,
String
pwd
,
String
type
);
}
src/main/java/login/implementor/abstractlogin/ThirdPartLogin.java
0 → 100644
浏览文件 @
5d62c194
package
login.implementor.abstractlogin
;
import
login.implementor.LoginFunc
;
public
class
ThirdPartLogin
extends
AbstractLoginProcessor
{
public
ThirdPartLogin
(
LoginFunc
loginFunc
)
{
super
(
loginFunc
);
}
@Override
public
boolean
loginExecute
(
String
name
,
String
pwd
,
String
type
)
{
return
super
.
loginFunc
.
login
(
name
,
pwd
,
type
);
}
}
src/main/resources/application.properties
0 → 100644
浏览文件 @
5d62c194
server.port
=
8080
### \u6BD4\u55BB\u6210\u914D\u7F6E\u4E2D\u5FC3
suggest.requirement.handler
=
com.study.design.handler.PersonnalCheckHandler,com.study.design.handler.CityCheckHandler,com.study.design.handler.RecentCheckHandler,com.study.design.handler.NewCheckHandler
\ No newline at end of file
src/main/resources/test
0 → 100644
浏览文件 @
5d62c194
{
"columns": [
{
"name": "username",
"type": "String"
},
{
"name": "age",
"type": "String"
}
],
"rows": [
[
"zhao",
"11"
],
[
"qian",
"12"
],
[
"sun",
"11"
],
[
"li",
"14"
],
[
"zhou",
"11"
]
],
"cursor": "DIXPnoOPhGJSDOIPANhnnaioHVNgyuyBKMLLYURrghoivpvptFTyguhuiOHIPBVGIYGFUYGFFYVfuvyhubiOHIOHIoht78t78t786rt6r7RFFYVJVHJVHJbkjbkj=="
}
=======================================================================================
{
"rows": [
[
"wu",
"9"
],
[
"zheng",
"11"
],
[
"wang",
"11"
]
]
}
======================================
普通策略:
1. 进行第一次访问,然后获取 columns ,rows 和 cursor。
2. 转化我们的第一次结果为 map 形式的 json
3. 拿第一次的 corsor id,进行第二次访问。
4. 用第一次记录的 columns 组装第二次的 rows结果为 map 形式的json
以此类推。
5. 把所有的转化结果存储到 一个 对象(数据量太大,占用内存)里,返回给调用者
(数据量太大,带宽受不了)。
升级策略:迭代器模式
1. 将我们访问封装到我们的迭代器中;(第一次访问以迭代器的构造函数访问,初始化我们的columns供
后续使用;将第一次的结果转化为 map 形式的json 供 迭代器使用)
2. hasnext 方法里,进行我们的后续的多次访问。
1. DB 存储
id parentId name
1 0 书籍
--------------------------
2 1 技术书籍
---------------------------
3 1 历史书籍
---------------------------
4 2 并发编程
---------------------------
5 2 JVM
2. 当我们的项目进行初始化的时候,就会将我们的DB里的这些目录进行如下的查询转化为如下对象存储:
{
"id": 1,
"itemName": "书籍",
"pid": 0,
"childItems": [{
"id": 2,
"itemName": "技术书籍",
"pid": 1,
"childItems": [{
"id": 4,
"itemName": "并发编程",
"pid": 2,
"childItems": null
}, {
"id": 5,
"itemName": "JVM",
"pid": 2,
"childItems": null
}]
}, {
"id": 3,
"itemName": "历史书籍",
"pid": 1,
"childItems": null
}]
}
3. 将这个对象存储到我们的 Nginx 本地缓存,并设置为永不过期。
4. App 、 页面进行调用的时候,从 Nginx 获取这份儿目录。并且 APP 端进行缓存,每隔 24小时进行一次 标记位的访问(如果业务对我们的目录结构有增删,标记位(序号)就会有所变化,前端会再次对数据进行重新的同步)
5. 如果有修改,后端是先 修改缓存,只针对缓存中需要修改的部分进行修改,然后更新缓存(目录层结构+标志位)。 缓存更新成功后,再更新DB.
src/test/java/com/study/design/DesignApplicationTests.java
0 → 100644
浏览文件 @
5d62c194
package
com.study.design
;
import
org.junit.jupiter.api.Test
;
import
org.springframework.boot.test.context.SpringBootTest
;
@SpringBootTest
class
DesignApplicationTests
{
@Test
void
contextLoads
()
{
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录