GoLang设计模式13 - 空对象模式(行为型)

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

空对象模式的组件包括:

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

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

求:各大学里所有系教授数量和

可获得对象:

  1. 所有大学的系的名称列表

  2. 大学对象

解法:大学对象调用方法,以系名称为参数,获取系对象,有可能获取空对象。获取系对象后,调用系方法获取系教授数量,空对象教授数量为0

//系的抽象
type department interface {
    getNumberOfProfessors() int
    getName() string
}

//null系的实现
type nullDepartment struct {
    numberOfProfessors int
}

func (c *nullDepartment) getNumberOfProfessors() int {
    return 0
}

func (c *nullDepartment) getName() string {
    return "nullDepartment"
}

//计算机科学系的实现
type computerScience struct {
    numberOfProfessors int
}

func (c *computerScience) getNumberOfProfessors() int {
    return c.numberOfProfessors
}

func (c *computerScience) getName() string {
    return "computerScience"
}

//数学系的实现
type mechanical struct {
    numberOfProfessors int
}

func (c *mechanical) getNumberOfProfessors() int {
    return c.numberOfProfessors
}

func (c *mechanical) getName() string {
    return "mechanical"
}

 

大学(college):

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 exits
    return &nullDepartment{}
}

main:

 1 func main() {
 2     college1 := createCollege1()
 3     college2 := createCollege2()
 4     totalProfessors := 0
 5     departmentArray := []string{"computerScience", "mechanical", "civil", "electronics"}
 6  
 7     for _, departmentName := range departmentArray {
 8         d := college1.getDepartment(departmentName)
 9         totalProfessors += d.getNumberOfProfessors()
10     }
11  
12     fmt.Printf("Total number of professors in college1 is %d\n", totalProfessors)
13  
14     //Reset the professor count
15     totalProfessors = 0
16     for _, departmentName := range departmentArray {
17         d := college2.getDepartment(departmentName)
18         totalProfessors += d.getNumberOfProfessors()
19     }
20     fmt.Printf("Total number of professors in college2 is %d\n", totalProfessors)
21 }
22  
23 func createCollege1() *college {
24     college := &college{}
25     college.addDepartment("computerScience", 4)
26     college.addDepartment("mechanical", 5)
27     return college
28 }
29  
30 func createCollege2() *college {
31     college := &college{}
32     college.addDepartment("computerScience", 2)
33     return college
34 }

 

输出内容如下:

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

 

posted @ 2023-04-21 11:34  格局打得开  阅读(77)  评论(0)    收藏  举报