代码优化-第一弹扩展接口

这两天写一些代码,发现有不少重复劳动,因此借此机会梳理下代码是怎样进化的,以密码验证位例。

密码验证规则:

1.长度超过8位。

2.包括大小写字母.数字.其它符号,以上四种至少三种。

3.不能有长度大于2的包含公共元素的子串重复。

这三种规则通常我们会写三个函数就可以搞定,见下。

package main

import "fmt"

func main(){
    var s string
    fmt.Scanf("%s", &s)
    ResStatus := "OK"
    if len(s) < 8 {
        ResStatus = "NG"
    } else if !incThreeVarChars(s) {
        ResStatus = "NG"
    } else if !existSubstrLessThann(s, 3) {
        ResStatus = "NG"
    }
    fmt.Println(ResStatus)
}

// 包含三种字符
func incThreeVarChars(s string)bool{
    tp := make(map[byte]bool)
    for _,v := range s {
        if isNumber(byte(v)) {
            tp['1'] = true
        } else if isEngUpperChar(byte(v)) {
            tp['2'] = true
        } else if isEngLowerChar(byte(v)) {
            tp['3'] = true
        } else {
            tp['4'] = true
        }
    }
    if len(tp) < 3 {
        return false
    }
    return true
}
// 是数字
func isNumber(a byte)bool{
    if a >= '0' && a <= '9' {
        return true
    }
    return false
}
// 是大写字母
func isEngUpperChar(a byte)bool{
    if a >= 'A' && a <= 'Z' {
        return true
    }
    return false
}
// 是小写字母
func isEngLowerChar(a byte)bool{
    if a >= 'a' && a <= 'z' {
        return true
    }
    return false
}
// 是否存在低于n个字符相同子串
func existSubstrLessThann(s string, n)bool{
    f := true
    if len(s) <= n {
        return f
    }
    for i := 0; i < len(s)-n;i++{
        s1 := s[i:i+n]
        for j := i+1; j < len(s)-n;j++{
            s2 := s[j:j+n]
            if s1 != s2 {
                continue
            }
            f = false
            break
        }
    }
    return f
}

如果现在需要对这个密码验证器扩展为需要返回错误提示,我们需要更改代码并对每种规则返回对应的错误,若规则比较多这中编码不符合代码的修改哲学。

这里我把它改为一个验证器,一个规则接口,以及具体实现三块,期中验证器三个方法,AddRule是添加规则,Valide是验证规则,Error是错误收集器。

type Validator struct{
    r []IRule
}

func New()*Validator{
	return &Validator{}
}

func (s *Validator)AddRule(r rule){
    s.r = append(s.r, r)
}

func (s *Validator)Valide(){
    for _,v := range s.r {
        if err := v.Valid(); err != nil {
            s.errs = append(s.errs, err)
        }
    }
}
func (s *Validator)Errors()[]error{
	return s.errs
}

规则接口只需要Valid方法,以及Rule规则具体error类型。

type IRule interface {
     Valid(interface)error
}

type Rule struct {
    err error
    IRule
}

规则实现1,包含至少3种字符。

// 包含三种字符
type moreThanThreeKindsCharactorRule struct {
	Rule
}
func (s *moreThanThreeKindsCharactorRule)Valid(s string)error{
    tp := make(map[byte]bool)
    for _,v := range s {
        if isNumber(byte(v)) {
            tp['1'] = true
        } else if isEngUpperChar(byte(v)) {
            tp['2'] = true
        } else if isEngLowerChar(byte(v)) {
            tp['3'] = true
        } else {
            tp['4'] = true
        }
    }
    if len(tp) < 3 {
        return errors.New("少于超过3种字符")
    }
    return nil
}
// 是数字
func (s *moreThanThreeKindsCharactorRule)isNumber(a byte)bool{
    if a >= '0' && a <= '9' {
        return true
    }
    return false
}
// 是大写字母
func (s *moreThanThreeKindsCharactorRule)isEngUpperChar(a byte)bool{
    if a >= 'A' && a <= 'Z' {
        return true
    }
    return false
}
// 是小写字母
func (s *moreThanThreeKindsCharactorRule)isEngLowerChar(a byte)bool{
    if a >= 'a' && a <= 'z' {
        return true
    }
    return false
}

规则实现2,存在超过n个字符的子串。


// 是否存在低于n个字符相同子串
type existSubstrLessThannRule struct{
	Rule
}
func (s *existSubstrLessThannRule)Valid(s string, n int)error{
    f := true
    if len(s) <= n {
        return f
    }
    for i := 0; i < len(s)-n;i++{
        s1 := s[i:i+n]
        for j := i+1; j < len(s)-n;j++{
            s2 := s[j:j+n]
            if s1 != s2 {
                continue
            }
            f = false
            break
        }
    }
	if !f {
		return errors.New("存在低于3个字符相同子串")
	}
    return nil
}

代码调用

func main(){
    var s string
    fmt.Scanf("%s", &s)
    ResStatus := "OK"
	validator := NewValidator()
	
	validator.AddRule(moreThanThreeKindsCharactorRule{})
	validator.AddRule(existSubstrLessThannRule{})
	validator.Valide()
	if errs := validator.Errors(); len(errs) > 0 {
        ResStatus = "NG"
	}
    fmt.Println(ResStatus)
}

这种方式减少了更改以往的代码,但每增加一种规则需要增加一个struct。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值