zoukankan      html  css  js  c++  java
  • Golang 选项设计模式

    引入问题: 现有一个结构体,再声明一个用于初始化该结构体的构造方法, 进行对结构体字段赋值

    package main
    
    import "fmt"
    
    // 声明options结构体
    type Options struct {
    	str1 string
    	str2 string
    	int1 int
    	int2 int
    }
    
    // 声明构造方法进行初始化结构体
    func InitOptions() *Options {
    	return &Options{}
    }
    
    func main() {
    	options := InitOptions()
    	fmt.Printf("%#v", options)
    }
    

    普通方法实现

    在构造方法中声明结构体的每一个字段值,且要和结构体中的字段位置进行对照

    package main
    
    import "fmt"
    
    // 声明options结构体
    type Options struct {
    	str1 string
    	str2 string
    	int1 int
    	int2 int
    }
    
    // 声明构造方法进行初始化结构体
    func InitOptions(str1 string, str2 string, int1 int, int2 int) *Options {
    	options := &Options{}
    	options.str1 = str1
    	options.str2 = str2
    	options.int1 = int1
    	options.int2 = int2
    	return options
    }
    
    func main() {
    	options := InitOptions("a", "b", 1, 2)
    	fmt.Printf("%#v", options)
    }
    

    此方法的问题: 当结构体每增加一个字段都需要进行对构造函数就行修改,并且对结构体字段增加的个数和字段类型具有不确定性,如果要修改的化这种方法看着比较繁琐,而且代码看着也比较 low

    第二种普通写法

    看上面的写法字段的个数和字段的类型都是不确定的,我们可以将构造参数变为一个可变的传参方式,并且传入的参数是一个 interface 类型的,之后通过遍历参数给结构体赋值

    package main
    
    import "fmt"
    
    // 声明options结构体
    type Options struct {
    	str1 string
    	str2 string
    	int1 int
    	int2 int
    }
    
    // 声明构造方法进行初始化结构体
    func InitOptions(opts ...interface{}) *Options {
    	options := &Options{}
    	for index, val := range opts {
    		switch index {
    		case 1:
    			v, _ := val.(string)
    			options.str1 = v
    		case 2:
    			v, _ := val.(string)
    			options.str2 = v
    		case 3:
    			v, _ := val.(int)
    			options.int1 = v
    
    		case 4:
    			v, _ := val.(int)
    			options.int2 = v
    		}
    	}
    
    	return options
    }
    
    func main() {
    	options := InitOptions("a", "b", 1, 2)
    	fmt.Printf("%#v", options)
    }
    

    这种方法看着也是比较繁琐,但是我们确定了构造函数需要的参数个数和类型是不确定的,那我们就引入使用选项设计模式进行改造

    选项设计模式实现

    1. 声明一个 Option 变量类型,类型为一个函数类型,函数类型接收一个指针类型的 Options 结构体
    2. 构造函接受一个可变长度的 Option 变量类型
    3. 之后没增加一个字段创建一个指定格式类型的函数,传入构造函数即可初始化结构体

    代码如下:

    package main
    
    import "fmt"
    
    // 声明options结构体
    type Options struct {
    	str1 string
    	str2 string
    	int1 int
    	int2 int
    }
    
    // 声明一个变量类型,变量接收一个Options结构体的指针类型
    type Option func(opts *Options)
    
    // 声明构造方法进行初始化结构体
    func InitOptions(opts ...Option) *Options {
    	options := &Options{}
    	for _, opt := range opts {
    		opt(options)
    	}
    	return options
    }
    
    func WithOptionStr1(str string) Option {
    	return func(opts *Options) {
    		opts.str1 = str
    	}
    }
    
    func WithOptionStr2(str string) Option {
    	return func(opts *Options) {
    		opts.str2 = str
    	}
    }
    
    func WithOptionInt1(i int) Option {
    	return func(opts *Options) {
    		opts.int1 = i
    	}
    }
    
    func WithOptionInt2(i int) Option {
    	return func(opts *Options) {
    		opts.int2 = i
    	}
    }
    
    func main() {
    	options := InitOptions(
    		WithOptionStr1("a"),
    		WithOptionStr2("b"),
    		WithOptionInt1(1),
    		WithOptionInt2(2),
    	)
    	fmt.Printf("%#v", options)
    }
    
  • 相关阅读:
    win7跨网段加域提示"找不到网络路径",解决后又提示"将该计算机的主域DNS更改为“”失败,名称仍然为xx.xx, 错误为“指定的服务器无法运行请求的操作”!
    XP原版系统激活
    使用SQLyog远程连接mysql,错误1130 解决方法
    激活Windows Server 2008 R2 Enterprise 方法
    Non-UTF-8 code starting with 'xff'解决,记录
    Linux 中,基础命令 command not found...问题
    winxp_sp3未激活的登录问题
    linux安装tomcat
    Notepad++ 配置python
    python idle 清屏问题的解决
  • 原文地址:https://www.cnblogs.com/zhichaoma/p/12509110.html
Copyright © 2011-2022 走看看