// 人類角色特征
type HumanTrait interface {
CastHuman() *Human
}
// 學生角色特征
type StudentTrait interface {
CastStudent() *Student
}
// 員工角色特征
type WorkerTrait interface {
CastWorker() *Worker
}
// 游玩者角色特征
type EnjoyerTrait interface {
CastEnjoyer() *Enjoyer
}
Student、Worker、Enjoyer組合HumanTrait,并通過Compose(HumanTrait)方法進行特征注入,只要在注入的時候保證Human是同一個,就可以解決該問題了。
// 學生角色
type Student struct {
// Student同時也是個普通人,因此組合了Human角色
HumanTrait
data.StudentCard
}
// 注入人類角色特征
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同時也是個普通人,因此組合了Human角色
HumanTrait
data.WorkCard
}
// 注入人類角色特征
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同時也是個普通人,因此組合了Human角色
HumanTrait
}
// 注入人類角色特征
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)
}
最后,實現People這一領域對象:
package object
type People struct {
// People對象扮演的角色
role.Human
role.Student
role.Worker
role.Enjoyer
}
// People實現了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在初始化時,完成對角色特征的注入
func NewPeople(name string) *People {
// 一些初始化的邏輯...
people.Student.Compose(people)
people.Worker.Compose(people)
people.Enjoyer.Compose(people)
return people
}
進行角色拆分之后,在實現Home、School、Company、Park等場景時,只需依賴相應的角色即可,不再需要依賴People這一領域對象:
// 家
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
}
// 執行Home的業務邏輯
func (h *Home) Run() {
h.me.Eat()
h.me.PlayGame()
h.me.Sleep()
}
// 學校
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)
}
// 執行School的業務邏輯
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)
}
// 執行Company的業務邏輯
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)
}
// 執行Park的業務邏輯
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")
}
模型的運行方法如下:
paul := object.NewPeople("Paul")
mit := context.NewSchool("MIT")
google := context.NewCompany("Google")
home := context.NewHome()
summerPalace := context.NewPark("Summer Palace")
// 上學
mit.Receive(paul.CastStudent())
mit.Run()
// 回家
home.ComeBack(paul.CastHuman())
home.Run()
// 工作
google.Employ(paul.CastWorker())
google.Run()
// 公園游玩
summerPalace.Welcome(paul.CastEnjoyer())
summerPalace.Run()
寫在最后
從前文所描述的場景中,我們可以發現傳統的DDD/面向對象設計方法在對行為進行建模方面存在著不足,進而導致了所謂的 貧血模型和充血模型之爭 。
DCI架構的出現很好的彌補了這一點,它通過引入角色扮演的思想,巧妙地解決了充血模型中上帝類和模塊間耦合問題,而且不影響模型的正確性。當然,DCI架構也不是萬能的,在行為較少的業務模型中,使用DCI來建模并不合適。
最后,將DCI架構總結成一句話就是: 領域對象(Object)在不同的場景(Context)中扮演(Cast)不同的角色(Role),角色之間通過交互(Interactive)來完成具體的業務邏輯 。
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。
舉報投訴
-
編程語言
+關注
關注
10文章
1964瀏覽量
39578 -
應用程序
+關注
關注
38文章
3344瀏覽量
60262 -
DCI
+關注
關注
0文章
42瀏覽量
7235 -
面向對象編程
+關注
關注
0文章
22瀏覽量
2163
發布評論請先 登錄
相關推薦
熱點推薦
DCI 顛覆光器件產業?
會遍嘗苦果,但是這種重新定義行業標準的大膽的行動,一下子顛覆了人們的認知。光器件未來到底要遵循什么樣的技術和質量標準?由于光模塊不僅要使用于低環境要求的DCI,也需要使用于其它如電信應用的高標準環境
發表于 02-08 15:53
DDR3控制器和SSTL15_T_DCI在同一個bank中
你好,我使用Virtex7的HP庫來實現DDR3控制器。我的控制器將以1600Mbps的速度運行,因此主控制器中的VRN和VRP應連接一個80Ω電阻,以實現更高的性能。實現addr / cmd信號
發表于 03-25 11:04
為什么銀行也沒有DCI匹配?
在ml_605的示意圖中,我發現在一個銀行(例如銀行16)中混合了LVDS信號和信號端信號,所以銀行應該收起2.5v,并且銀行有DCI匹配。但是在銀行24(銀行混合了LVDS信號和信號端信號),所以
發表于 10-25 08:47
如何在IBIS文件中配置SSTL135 DCI阻抗
嗨,我正在嘗試使用Hyperlynx來模擬K7上的DDR3L設計。我使用Vivado write_ibis根據我的FPGA設計生成ibis文件。對于SSTL135_DCI_HP_IN50_I信號,我
發表于 07-14 09:10
DCI是什么?Xilinx 7系列FPGA的HP bank都支持DCI
Xilinx 7系列FPGA的HP bank都支持DCI,目的是在高速單板信號傳輸中保持信號完整性,減少反射等因素影響,那么DCI是什么?digitally controlled impedance
發表于 06-27 09:11
?2.1w次閱讀
什么是DCI-BOX?為什么會出現這個東西?
但為什么會出現這個東西?在我看來,主要是場景和成本兩方面決定。場景上,DCI-BOX說高大上一點是面向新一代城域網的架構,如城域分發(POD),云網入網點(POP)等功能區的應用場景。
DCI BOX與傳統WDM/OTN設備有什么區別?
DCI-BOX,中國聯通叫模塊化波分設備,中國電信叫盒式波分設備DCI-BOX,是數據中心點到點互連(DCI)的設備。在DCI BOX出現之前,DC
易飛揚非相干DCI BOX的DCI傳輸方案介紹
易飛揚推出的最新1U 800G DWDM DCI BOX是一款1U盒式的多業務波分傳輸平臺,可滿足最大8×100GE業務點對點傳輸的應用場景,單機框常規接入容量800G。它同樣滿足DCI對小體積、低功耗、極簡維護、低時延、大帶寬的需求。
發表于 04-21 10:39
?1095次閱讀
非相干DCI BOX,提供更經濟的DCI傳輸方案
易飛揚推出的最新1U 800G DWDM DCI BOX是一款1U盒式的多業務波分傳輸平臺,可滿足最大8×100GE業務點對點傳輸的應用場景,單機框常規接入容量800G。它同樣滿足DCI對小體積、低功耗、極簡維護、低時延、大帶寬的需求。
非相干DCI BOX,提供更經濟的DCI傳輸方案
上文,我們介紹了相干DCI BOX完美適配目前DCI傳輸的應用,不過,相干子系統的成本向來比較高,那是否有成本較低的非相干設備可供選擇?考慮到不同用戶的預算需求,易飛揚同樣提供經濟型的非相干DCI BOX,本文介紹的1U 800
如何實現DCI架構(上)
在面向對象編程的理念里,應用程序是對現實世界的抽象,我們經常會將現實中的事物建模為編程語言中的類/對象(“ **是什么** ”),而事物的行為則建模為方法(“ **做什么** ”)。面向對象編程有 **三大基本特性** (封裝、繼承/組合、多態)和 **五大基本原則** (單一職責原則、開放封閉原則、里氏替換原則、依賴倒置原則、接口分離原則),但知道這些還并不足以讓我們設計出好的程序,于是很多方法論就涌現了出來。
如何實現DCI架構(中)
在面向對象編程的理念里,應用程序是對現實世界的抽象,我們經常會將現實中的事物建模為編程語言中的類/對象(“ **是什么** ”),而事物的行為則建模為方法(“ **做什么** ”)。面向對象編程有 **三大基本特性** (封裝、繼承/組合、多態)和 **五大基本原則** (單一職責原則、開放封閉原則、里氏替換原則、依賴倒置原則、接口分離原則),但知道這些還并不足以讓我們設計出好的程序,于是很多方法論就涌現了出來。
如何實現DCI架構(下)
評論