設計模式:Observer 觀察者模式

Observer 觀察者模式

在軟件構建過程中,我們需要爲某些對象建立一種“通知依賴關係” ——一個對象(目標對象)的狀態發生改變,所有的依賴對象(觀察者對象)都將得到通知。如果這樣的依賴關係過於緊密,將使軟件不能很好地抵禦變化

使用面向對象技術,可以將這種依賴關係弱化,並形成一種穩定的依賴關係。從而實現軟件體系結構的鬆耦合。

定義對象間的一種一對多(變化)的依賴關係,以便當一個對象(Subject)的狀態發生改變時,所有依賴於它的對象都得到通知並自動更新。

使用面向對象的抽象,Observer模式使得我們可以獨立地改變目標與觀察者,從而使二者之間的依賴關係達致鬆耦合。

目標發送通知時,無需指定觀察者,通知(可以攜帶通知信息作爲參數)會自動傳播

觀察者自己決定是否需要訂閱通知,目標對象對此一無所知

Observer模式是基於事件的UI框架中非常常用的設計模式,也是MVC模式的一個重要組成部分

golang

代碼:更改前

package obs

import "fmt"

type ProgressBar struct {}
func (p *ProgressBar) setValue(value float64) {
	fmt.Println(value)
}


type FileSplitter struct {
	Filename string
	FileNumber int
	Progress_bar *ProgressBar
}

func (f FileSplitter) Split() {
	// 1. 讀取文件
	// ....
	// 2. 分批次向小文件寫入
	for i:=0;i< f.FileNumber;i++{
		// ....
		// 設置進度
		f.Progress_bar.setValue(float64((i+1))/float64(f.FileNumber))
	}

}

代碼:更改後

package obs


type IProgram interface {
	DoProgress(float64)
}


type IPrograms struct {
	iprograms []*IProgram
}

func (ipr *IPrograms) OnProgress(value float64) {
	for _,iprogram := range ipr.iprograms{
		(*iprogram).DoProgress(value)
	}
}
func (ipr *IPrograms) Append(program IProgram) {
	ipr.iprograms = append(ipr.iprograms, &program)
}
func (ipr *IPrograms) Remove(program IProgram) {
	for i,iprogram := range ipr.iprograms{
		if iprogram == &program{
			ipr.iprograms = append(ipr.iprograms[:i],ipr.iprograms[i+1:]...)
		}
	}

}


type FileSplitter struct {
	Filename string
	FileNumber int
	IPrograms *IPrograms
}

func (f FileSplitter) Split() {
	// 1. 讀取文件
	// ....
	// 2. 分批次向小文件寫入
	for i:=0;i< f.FileNumber;i++{
		// ....
		// 設置進度
		f.IPrograms.OnProgress(float64(i+1)/float64(f.FileNumber))
	}
}

main.go

main.go
package main

import (
	"Methods/observer/obs"
	"fmt"
)



type ProgressBar struct {}

func (p ProgressBar) DoProgress(value float64) {
	fmt.Println(value)

}
type ProgressCount struct {}

func (p ProgressCount) DoProgress(value float64) {
	fmt.Printf("c_%v\n",value)

}
func main() {
	var p obs.IPrograms
	var pb = ProgressBar{}
	var pc = ProgressCount{}
	p.Append(pb)
	p.Append(pc)
	var f obs.FileSplitter = obs.FileSplitter{"test",5,&p}
	f.Split()
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章