zoukankan      html  css  js  c++  java
  • GoLang设计模式12 空对象模式

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

    空对象模式的组件包括:

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

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

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

    type department interface {
    	getNumberOfProfessors() int
    
    	getName() 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 := 0
    	departmentArray := []string{"computerScience", "mechanical", "civil", "electronics"}
    
    	for _, departmentName := range departmentArray {
    		d := college1.getDepartment(departmentName)
    		totalProfessors += d.getNumberOfProfessors()
    	}
    
    	fmt.Printf("Total number of professors in college1 is %d\n", totalProfessors)
    
    	//Reset the professor count
    	totalProfessors = 0
    	for _, 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 exits
    	return &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 9
    Total number of professors in college2 is 2
    

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

    End!!


    仅是学习笔记,难免出错,望不吝指点
  • 相关阅读:
    PAT (Basic Level) Practise 1013 数素数
    PAT (Basic Level) Practise 1014 福尔摩斯的约会
    codeforces 814B.An express train to reveries 解题报告
    KMP算法
    rsync工具
    codeforces 777C.Alyona and Spreadsheet 解题报告
    codeforces 798C.Mike and gcd problem 解题报告
    nginx + tomcat多实例
    MongoDB副本集
    指针的艺术(转载)
  • 原文地址:https://www.cnblogs.com/amunote/p/15518128.html
Copyright © 2011-2022 走看看