AI智能
改变未来

GoLang设计模式12 – 空对象模式

空对象设计模式是一种行为型设计模式,主要用于应对空对象的检查。使用这种设计模式可以避免对空对象进行检查。也就是说,在这种模式下,使用空对象不会造成异常。

空对象模式的组件包括:

  • Entity:接口,定义了子struct需要实现的方法
  • ConcreteEntity:实现了Entity 的具体struct
  • NullEntity:这个就表示了空对象,虽然也实现了Entity接口,但它的值都是空的
  • Client:这个类会获取Entity接口实现类的实例并使用它。这里并不关注实现类是
    ConcreteEntity

    还是

    NullEntity

    ,对二者会进行相同的处理。

用个例子来说一下:假设有一所大学,大学有多个系,每个系都有一定数量的教授。

系(department)可以用一个接口来表示:

type department interface {getNumberOfProfessors() intgetName() string}

大学(college)也是一个接口:

type college struct {departments []department}

现在假设有一个机构想统计下大学每个系的教授数量。

在这个例子里,假设大学里没有某个系,我们就会用到空对象模式。这里定义了一个

nullDepartment

来表示不存在的系。

nullDepartment.go:

type nullDepartment struct {numberOfProfessors int}func (c *nullDepartment) getNumberOfProfessors() int {return 0}func (c *nullDepartment) getName() string {return \"nullDepartment\"}

统计的代码在agency.go里:

func main() {college1 := createCollege1()college2 := createCollege2()totalProfessors := 0departmentArray := []string{\"computerScience\", \"mechanical\", \"civil\", \"electronics\"}for _, departmentName := range departmentArray {d := college1.getDepartment(departmentName)totalProfessors56c+= d.getNumberOfProfessors()}fmt.Printf(\"Total number of professors in college1 is %d\\n\", totalProfessors)//Reset the professor counttotalProfessors = 0for _, departmentName := range departmentArray {d := college2.getDepartment(departmentName)totalProfessors += d.getNumberOfProfessors()}fmt.Printf(\"Total number of professors in college2 is %d\\n\", totalProfessors)}func createCollege1() *college {college := &college{}college.addDepartment(\"computerScience\", 4)college.addDepartment(\"mechanical\", 5)return college}func createCollege2() *college {college := &college{}college.addDepartment(\"computerScience\", 2)return college}

注意这段代码:

  • agency.go 并不关心某个系在大学里是否存在。当这个系不存在时,大学只需要返回一个
    nullDepartment

    对象即可

  • agency.go 对
    nullDepartment

    对象和其他

    department

    实现类的对象做了相同处理,这之中不需要对空值进行检查,直接调用

    getNumberOfProfessors()

    就可以了

以上就是使用空对象模式的好处了。

下面是其他的代码。

college.go:

type college struct {departments []department}func (c *college) addDepartment(departmentName string, numOfProfessors int) {if departmentName == \"computerScience\" {computerScienceDepartment := &computerScience{numberOfProfessors: numOfProfessors}c.departments = append(c.departments, computerScienceDepartment)}if departmentName == \"mechanical\" {mechanicalDepartment := &mechanical{numberOfProfessors: numOfProfessors}c.departments = append(c.departments, mechanicalDepartment)}return}func (c *college) getDepartment(departmentName string) department {for _, department := range c.departments {if department.getName() == departmentName {return department}}//Return a null department if the department doesn\'t exitsreturn &nullDepartment{}}

计算机系,computerscience.go:

type computerScience struct {numberOfProfessors int}func (c *computerScience) getNumberOfProfessors() int {return c.numberOfProfessors}func (c *computerScience) getName() string {return \"computerScience\"}

数学系,mechanical.go:

type mechanical struct {numberOfProfessors int}func (c *mechanical) getNumberOfProfessors() int {return c.numberOfProfessors}func (c *mechanical) getName() string {return \"mechanical\"}

执行agency.go,输出内容如下:

Total number of professors in college1 is 9Total number of professors in college2 is 2

代码已上传至GitHub:zhyea / go-patterns / null-object-pattern

End!!

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » GoLang设计模式12 – 空对象模式