這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
對於一個模組或者系統,可能由很多個物件構成,而且這些對象之間可能存在相互的引用,在最壞的情況下,每一個對象都知道其他所有的對象,這無疑複雜化了對象之間的聯絡。雖然將一個系統分割成許多個物件通常可以增強可複用性,但是對象間相互串連的激增又會降低其可複用性,大量的相互串連使得一個對象似乎不太可能在沒有其他對象的支援下工作,系統資料表現為一個不可分割的整體,而且對系統的行為進行任何較大的改動都會十分困難。結果是你不得不定義大量的子類以定製系統的行為。因此,為了減少對象兩兩之間複雜的參考關聯性,使之成為一個松耦合的系統,我們需要使用中介者模式.
中介者模式:用一個中介對象來封裝一系列的對象互動。中介者使各對象不需要顯式地相互引用,從而使其耦合鬆散,而且可以獨立地改變它們之間的互動。中介者模式又稱為調停者模式。中介者模式化多對多依賴為一對多依賴。
原始碼:
package mainconst MaxClassSize = 50 //課程最大人數//中介者介面type Mediator interface {Register(Mediatable) // 將被協調者的對象儲存引用Mediate(string, ...interface{}) //協調不同對象的操作}//協同介面type Mediatable interface {SetMediator(Mediator)}//實現協同介面的簡單類,用於子類繼承type SimpleMediatable struct {mediator Mediator}func (s *SimpleMediatable) SetMediator(m Mediator) {s.mediator = m}//具體中介者type ConcreateMediator struct {coureses map[string]*Courseteachers map[string]*Teacherstudents map[string]*StudentcourseSelect map[string]([]*Student)}func NewConcreateMediator() *ConcreateMediator {return &ConcreateMediator{make(map[string]*Course), make(map[string]*Teacher), make(map[string]*Student), make(map[string]([]*Student))}}func (c *ConcreateMediator) Register(m Mediatable) {switch m.(type) {case *Course:cname := m.(*Course).Namec.coureses[cname] = m.(*Course)c.courseSelect[cname] = make([]*Student, MaxClassSize)case *Student:c.students[m.(*Student).Name] = m.(*Student)case *Teacher:c.teachers[m.(*Teacher).Name] = m.(*Teacher)}}func (c *ConcreateMediator) Mediate(t string, v ...interface{}) {switch t {case "teach":if courseName, ok := v[0].(string); ok {for num, i, stds := c.coureses[courseName].StdNum, 0, c.courseSelect[courseName]; i < num; i++ {stds[i].listening()println(courseName)}}case "select":if std, ok := v[0].(*Student); ok {if courseName, ok := v[1].(string); ok {pos := &c.coureses[courseName].StdNumc.courseSelect[courseName][*pos] = std*pos++}}}}type Student struct {SimpleMediatableName string}func NewStudent(name string, m Mediator) *Student {s := new(Student)s.Name = names.SetMediator(m)m.Register(s)return s}func (s *Student) selectCourse(cname string) {s.mediator.Mediate("select", s, cname)}func (s *Student) listening() {print(s.Name + " is listening ")}type Course struct {SimpleMediatableName stringStdNum intTeacherName string}func NewCourse(name, tname string, m Mediator) *Course {c := new(Course)c.Name, c.TeacherName = name, tnamec.SetMediator(m)m.Register(c)return c}type Teacher struct {SimpleMediatableName string}func NewTeacher(name string, m Mediator) *Teacher {s := new(Teacher)s.Name = names.SetMediator(m)m.Register(s)return s}func (t *Teacher) teachCourse(cname string) {t.mediator.Mediate("teach", cname)}func main() {mediatorA := NewConcreateMediator()NewCourse("Math", "Pen TieZhao", mediatorA)NewCourse("Computer", "Liu ZhiRong", mediatorA)std1 := NewStudent("LiChao", mediatorA)std2 := NewStudent("Readen", mediatorA)std3 := NewStudent("Herry", mediatorA)std4 := NewStudent("John", mediatorA)std5 := NewStudent("Richer", mediatorA)std6 := NewStudent("Barry", mediatorA)tch1 := NewTeacher("Pen TieZhao", mediatorA)tch2 := NewTeacher("Liu ZhiRong", mediatorA)std1.selectCourse("Math")std1.selectCourse("Computer")std2.selectCourse("Computer")std3.selectCourse("Math")std4.selectCourse("Math")std4.selectCourse("Computer")std5.selectCourse("Computer")std6.selectCourse("Computer")tch1.teachCourse("Math")tch2.teachCourse("Computer")}
運行結果:
`go run Mediator.go` | done: 1.71875s ]LiChao is listening MathHerry is listening MathJohn is listening MathLiChao is listening ComputerReaden is listening ComputerJohn is listening ComputerRicher is listening ComputerBarry is listening Computer