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!!


    仅是学习笔记,难免出错,望不吝指点
  • 相关阅读:
    模拟ORA-26040: Data block was loaded using the NOLOGGING option
    poj 2752 Seek the Name, Seek the Fame (KMP纯模版)
    一入python深似海--变量和对象
    Codeforces 448 C. Painting Fence
    Unix网络编程 高级IO套接字设置超时
    [ JavaScript ] JavaScript 实现继承.
    讲座:与迷茫为友的成长
    分享:进化版动漫更新提醒(微信及软件)
    设计模式------模板方法模式
    BasePath问题-nginx负载均衡配置
  • 原文地址:https://www.cnblogs.com/amunote/p/15518128.html
Copyright © 2011-2022 走看看