0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何实现DCI架构(下)

jf_78858299 来源:元闰子的邀请 作者:元闰子 2023-05-10 17:10 次阅读

为解决该问题,我们引入了xxxTrait接口

// 人类角色特征
type HumanTrait interface {
 CastHuman() *Human
}
// 学生角色特征
type StudentTrait interface {
 CastStudent() *Student
}
// 员工角色特征
type WorkerTrait interface {
 CastWorker() *Worker
}
// 游玩者角色特征
type EnjoyerTrait interface {
 CastEnjoyer() *Enjoyer
}

StudentWorkerEnjoyer组合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
}

进行角色拆分之后,在实现HomeSchoolCompanyPark等场景时,只需依赖相应的角色即可,不再需要依赖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

    文章

    1939

    浏览量

    34605
  • 应用程序
    +关注

    关注

    37

    文章

    3244

    浏览量

    57610
  • DCI
    DCI
    +关注

    关注

    0

    文章

    39

    浏览量

    6807
  • 面向对象编程

    关注

    0

    文章

    22

    浏览量

    1807
收藏 人收藏

    评论

    相关推荐

    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

    GD32F207-DCI

    单片机GD32F207学习例程之GD32F207-DCI例程源码
    发表于 06-03 15:40 10次下载

    DCI是什么?Xilinx 7系列FPGA的HP bank都支持DCI

    Xilinx 7系列FPGA的HP bank都支持DCI,目的是在高速单板信号传输中保持信号完整性,减少反射等因素影响,那么DCI是什么?digitally controlled impedance
    发表于 06-27 09:11 1.9w次阅读
    <b class='flag-5'>DCI</b>是什么?Xilinx 7系列FPGA的HP bank都支持<b class='flag-5'>DCI</b>

    什么是DCI-BOX?为什么会出现这个东西?

    但为什么会出现这个东西?在我看来,主要是场景和成本两方面决定。场景上,DCI-BOX说高大上一点是面向新一代城域网的架构,如城域分发(POD),云网入网点(POP)等功能区的应用场景。
    的头像 发表于 11-18 09:35 1.2w次阅读

    DCI BOX与传统WDM/OTN设备有什么区别?

    DCI-BOX,中国联通叫模块化波分设备,中国电信叫盒式波分设备DCI-BOX,是数据中心点到点互连(DCI)的设备。在DCI BOX出现之前,DC
    的头像 发表于 03-26 14:29 1730次阅读

    DCI BOX与传统WDM/OTN设备有什么区别?

    DCI BOX出现之前,DCI通常使用WDM/OTN设备进行互连,那么两者之间有什么区别呢?
    的头像 发表于 03-27 15:37 1104次阅读

    易飞扬全新升级DCI BOX,照亮DCI传输网络

    易飞扬2U 6.4T DCI BOX
    的头像 发表于 04-14 17:46 1112次阅读
    易飞扬全新升级<b class='flag-5'>DCI</b> BOX,照亮<b class='flag-5'>DCI</b>传输网络

    易飞扬非相干DCI BOX的DCI传输方案介绍

    易飞扬推出的最新1U 800G DWDM DCI BOX是一款1U盒式的多业务波分传输平台,可满足最大8×100GE业务点对点传输的应用场景,单机框常规接入容量800G。它同样满足DCI对小体积、低功耗、极简维护、低时延、大带宽的需求。
    发表于 04-21 10:39 526次阅读

    非相干DCI BOX,提供更经济的DCI传输方案

    易飞扬推出的最新1U 800G DWDM DCI BOX是一款1U盒式的多业务波分传输平台,可满足最大8×100GE业务点对点传输的应用场景,单机框常规接入容量800G。它同样满足DCI对小体积、低功耗、极简维护、低时延、大带宽的需求。
    的头像 发表于 04-21 10:40 853次阅读

    非相干DCI BOX,提供更经济的DCI传输方案

    上文,我们介绍了相干DCI BOX完美适配目前DCI传输的应用,不过,相干子系统的成本向来比较高,那是否有成本较低的非相干设备可供选择?考虑到不同用户的预算需求,易飞扬同样提供经济型的非相干DCI BOX,本文介绍的1U 800
    的头像 发表于 04-24 09:46 855次阅读
    非相干<b class='flag-5'>DCI</b> BOX,提供更经济的<b class='flag-5'>DCI</b>传输方案

    如何实现DCI架构(上)

    在面向对象编程的理念里,应用程序是对现实世界的抽象,我们经常会将现实中的事物建模为编程语言中的类/对象(“ **是什么** ”),而事物的行为则建模为方法(“ **做什么** ”)。面向对象编程有 **三大基本特性** (封装、继承/组合、多态)和 **五大基本原则** (单一职责原则、开放封闭原则、里氏替换原则、依赖倒置原则、接口分离原则),但知道这些还并不足以让我们设计出好的程序,于是很多方法论就涌现了出来。
    的头像 发表于 05-10 17:09 678次阅读
    如何<b class='flag-5'>实现</b><b class='flag-5'>DCI</b><b class='flag-5'>架构</b>(上)

    如何实现DCI架构(中)

    在面向对象编程的理念里,应用程序是对现实世界的抽象,我们经常会将现实中的事物建模为编程语言中的类/对象(“ **是什么** ”),而事物的行为则建模为方法(“ **做什么** ”)。面向对象编程有 **三大基本特性** (封装、继承/组合、多态)和 **五大基本原则** (单一职责原则、开放封闭原则、里氏替换原则、依赖倒置原则、接口分离原则),但知道这些还并不足以让我们设计出好的程序,于是很多方法论就涌现了出来。
    的头像 发表于 05-10 17:10 658次阅读
    如何<b class='flag-5'>实现</b><b class='flag-5'>DCI</b><b class='flag-5'>架构</b>(中)