// 人類(lèi)角色特征
type HumanTrait interface {
CastHuman() *Human
}
// 學(xué)生角色特征
type StudentTrait interface {
CastStudent() *Student
}
// 員工角色特征
type WorkerTrait interface {
CastWorker() *Worker
}
// 游玩者角色特征
type EnjoyerTrait interface {
CastEnjoyer() *Enjoyer
}
Student
、Worker
、Enjoyer
組合HumanTrait
,并通過(guò)Compose(HumanTrait)
方法進(jìn)行特征注入,只要在注入的時(shí)候保證Human
是同一個(gè),就可以解決該問(wèn)題了。
// 學(xué)生角色
type Student struct {
// Student同時(shí)也是個(gè)普通人,因此組合了Human角色
HumanTrait
data.StudentCard
}
// 注入人類(lèi)角色特征
func (s *Student) Compose(trait HumanTrait) {
s.HumanTrait = trait
}
func (s *Student) Study() {
fmt.Printf("Student %+v studying\\n", s.StudentCard)
}
func (s *Student) Exam() {
fmt.Printf("Student %+v examing\\n", s.StudentCard)
}
// 員工角色
type Worker struct {
// Worker同時(shí)也是個(gè)普通人,因此組合了Human角色
HumanTrait
data.WorkCard
}
// 注入人類(lèi)角色特征
func (w *Worker) Compose(trait HumanTrait) {
w.HumanTrait = trait
}
func (w *Worker) Work() {
fmt.Printf("%+v working\\n", w.WorkCard)
w.CastHuman().Balance++
}
func (w *Worker) OffWork() {
fmt.Printf("%+v getting off work\\n", w.WorkCard)
}
// 游玩者角色
type Enjoyer struct {
// Enjoyer同時(shí)也是個(gè)普通人,因此組合了Human角色
HumanTrait
}
// 注入人類(lèi)角色特征
func (e *Enjoyer) Compose(trait HumanTrait) {
e.HumanTrait = trait
}
func (e *Enjoyer) BuyTicket() {
fmt.Printf("%+v buying a ticket\\n", e.CastHuman().IdentityCard)
e.CastHuman().Balance--
}
func (e *Enjoyer) Enjoy() {
fmt.Printf("%+v enjoying scenery\\n", e.CastHuman().IdentityCard)
}
最后,實(shí)現(xiàn)People
這一領(lǐng)域?qū)ο螅?/p>
package object
type People struct {
// People對(duì)象扮演的角色
role.Human
role.Student
role.Worker
role.Enjoyer
}
// People實(shí)現(xiàn)了HumanTrait、StudentTrait、WorkerTrait、EnjoyerTrait等特征接口
func (p *People) CastHuman() *role.Human {
return &p.Human
}
func (p *People) CastStudent() *role.Student {
return &p.Student
}
func (p *People) CastWorker() *role.Worker {
return &p.Worker
}
func (p *People) CastEnjoyer() *role.Enjoyer {
return &p.Enjoyer
}
// People在初始化時(shí),完成對(duì)角色特征的注入
func NewPeople(name string) *People {
// 一些初始化的邏輯...
people.Student.Compose(people)
people.Worker.Compose(people)
people.Enjoyer.Compose(people)
return people
}
進(jìn)行角色拆分之后,在實(shí)現(xiàn)Home
、School
、Company
、Park
等場(chǎng)景時(shí),只需依賴(lài)相應(yīng)的角色即可,不再需要依賴(lài)People
這一領(lǐng)域?qū)ο螅?/p>
// 家
type Home struct {
me *role.Human
}
func (h *Home) ComeBack(human *role.Human) {
fmt.Printf("%+v come back home\\n", human.IdentityCard)
h.me = human
}
// 執(zhí)行Home的業(yè)務(wù)邏輯
func (h *Home) Run() {
h.me.Eat()
h.me.PlayGame()
h.me.Sleep()
}
// 學(xué)校
type School struct {
Name string
students []*role.Student
}
func (s *School) Receive(student *role.Student) {
// 初始化StduentCard邏輯 ...
s.students = append(s.students, student)
fmt.Printf("%s Receive stduent %+v\\n", s.Name, student.StudentCard)
}
// 執(zhí)行School的業(yè)務(wù)邏輯
func (s *School) Run() {
fmt.Printf("%s start class\\n", s.Name)
for _, student := range s.students {
student.Study()
}
fmt.Println("students start to eating")
for _, student := range s.students {
student.CastHuman().Eat()
}
fmt.Println("students start to exam")
for _, student := range s.students {
student.Exam()
}
fmt.Printf("%s finish class\\n", s.Name)
}
// 公司
type Company struct {
Name string
workers []*role.Worker
}
func (c *Company) Employ(worker *role.Worker) {
// 初始化WorkCard邏輯 ...
c.workers = append(c.workers, worker)
fmt.Printf("%s Employ worker %s\\n", c.Name, worker.WorkCard.Name)
}
// 執(zhí)行Company的業(yè)務(wù)邏輯
func (c *Company) Run() {
fmt.Printf("%s start work\\n", c.Name)
for _, worker := range c.workers {
worker.Work()
}
fmt.Println("worker start to eating")
for _, worker := range c.workers {
worker.CastHuman().Eat()
}
fmt.Println("worker get off work")
for _, worker := range c.workers {
worker.OffWork()
}
fmt.Printf("%s finish work\\n", c.Name)
}
// 公園
type Park struct {
Name string
enjoyers []*role.Enjoyer
}
func (p *Park) Welcome(enjoyer *role.Enjoyer) {
fmt.Printf("%+v come park %s\\n", enjoyer.CastHuman().IdentityCard, p.Name)
p.enjoyers = append(p.enjoyers, enjoyer)
}
// 執(zhí)行Park的業(yè)務(wù)邏輯
func (p *Park) Run() {
fmt.Printf("%s start to sell tickets\\n", p.Name)
for _, enjoyer := range p.enjoyers {
enjoyer.BuyTicket()
}
fmt.Printf("%s start a show\\n", p.Name)
for _, enjoyer := range p.enjoyers {
enjoyer.Enjoy()
}
fmt.Printf("show finish\\n")
}
模型的運(yùn)行方法如下:
paul := object.NewPeople("Paul")
mit := context.NewSchool("MIT")
google := context.NewCompany("Google")
home := context.NewHome()
summerPalace := context.NewPark("Summer Palace")
// 上學(xué)
mit.Receive(paul.CastStudent())
mit.Run()
// 回家
home.ComeBack(paul.CastHuman())
home.Run()
// 工作
google.Employ(paul.CastWorker())
google.Run()
// 公園游玩
summerPalace.Welcome(paul.CastEnjoyer())
summerPalace.Run()
寫(xiě)在最后
從前文所描述的場(chǎng)景中,我們可以發(fā)現(xiàn)傳統(tǒng)的DDD/面向?qū)ο笤O(shè)計(jì)方法在對(duì)行為進(jìn)行建模方面存在著不足,進(jìn)而導(dǎo)致了所謂的 貧血模型和充血模型之爭(zhēng) 。
DCI架構(gòu)的出現(xiàn)很好的彌補(bǔ)了這一點(diǎn),它通過(guò)引入角色扮演的思想,巧妙地解決了充血模型中上帝類(lèi)和模塊間耦合問(wèn)題,而且不影響模型的正確性。當(dāng)然,DCI架構(gòu)也不是萬(wàn)能的,在行為較少的業(yè)務(wù)模型中,使用DCI來(lái)建模并不合適。
最后,將DCI架構(gòu)總結(jié)成一句話就是: 領(lǐng)域?qū)ο螅∣bject)在不同的場(chǎng)景(Context)中扮演(Cast)不同的角色(Role),角色之間通過(guò)交互(Interactive)來(lái)完成具體的業(yè)務(wù)邏輯 。
-
編程語(yǔ)言
+關(guān)注
關(guān)注
10文章
1945瀏覽量
34776 -
應(yīng)用程序
+關(guān)注
關(guān)注
37文章
3277瀏覽量
57737 -
DCI
+關(guān)注
關(guān)注
0文章
39瀏覽量
6836 -
面向?qū)ο缶幊?/span>
+關(guān)注
關(guān)注
0文章
22瀏覽量
1821
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論