在这种情况下,是不是更喜欢使用方法而不是函数?

huangapple go评论148阅读模式
英文:

Are methods instead of functions preferred in this case

问题

我有一整套类似这样的函数:

package rules;

import "project/some"

func frobDiscountLimit(frob some.Frob, maxDiscount float64) (RuleStatus, string) 
func frobDiscountPercentageLimit(frob some.Frob, maxDiscountPercentage float64) (RuleStatus, string) 
func frobUsageLimit(frob some.Frob, interval valueInterval) (RuleStatus, string) 
func frobPermanentExpiryLimit(frob some.Frob) (RuleStatus, string) 
func frobVoucherValidity(frob some.Frob, maxValidityDays uint) (RuleStatus, string) 

用法示例:

package rules

import "project/some"

func doChecks(frob some.Frob) {
    status, message := frobDiscountLimit(frob, 100)

    if status != PASSED {
       ....
    }

    ... 在这里评估所有剩余的规则 ...
}

我想知道是否有优势这样写:

func (f someFrob) discountLimit(maxDiscount float64) (RuleStatus, string) 
...

这样写似乎更简洁,但我不确定哪种是正确的风格。因为我不认为这些验证方法是“对象的一部分”,它们不是some.Frob对象的行为的一部分(不像是some.Frob的属性的getter或setter)。

英文:

I have a whole set of functions that look like this:

package rules;

import "project/some"

func frobDiscountLimit(frob some.Frob, maxDiscount float64) (RuleStatus, string) 
func frobDiscountPercentageLimit(frob some.Frob, maxDiscountPercentage float64) (RuleStatus, string) 
func frobUsageLimit(frob some.Frob, interval valueInterval) (RuleStatus, string) 
func frobPermanentExpiryLimit(frob some.Frob) (RuleStatus, string) 
func frobVoucherValidity(frob some.Frob, maxValidityDays uint) (RuleStatus, string) 

Usage example:

package rules

import "project/some"

func doChecks(frob some.Frob) {
    status, message := frobDiscountLimit(frob, 100)

    if status != PASSED {
       ....
    }

    ... evaluate all remaining rules here ...
}

I wonder is there any advantage writing it like:

func (f someFrob) discountLimit(maxDiscount float64) (RuleStatus, string) 
...

It seems shorter to write, but I'm unsure which is the correct style. Because I don't think of these validation methods as "part of the object", they are not part of the behaviour of the some.Frob object (unlike, say, a getter or a setter for property of some.Frob).

答案1

得分: 4

你可以这样做,避免反复显式传递 frob,同时仍然能够避免将这些函数作为 frob 的方法。

type frobChecker struct {
    frob some.Frob
}

func (fc frobChecker) discountLimit(maxDiscount float64) (RuleStatus, string) 
func (fc frobChecker) discountPercentageLimit(maxDiscountPercentage float64) (RuleStatus, string) 
func (fc frobChecker) usageLimit(interval valueInterval) (RuleStatus, string) 
func (fc frobChecker) permanentExpiryLimit() (RuleStatus, string) 
func (fc frobChecker) voucherValidity(maxValidityDays uint) (RuleStatus, string) 

func doChecks(frob some.Frob) {
    fc := frobChecker{frob}

    status, message := fc.discountLimit(100)

    if status != PASSED {
       ....
    }

    ... 在这里评估所有剩余的规则 ...
}

以上代码示例中,定义了一个名为 frobChecker 的结构体,其中包含一个 frob 的成员变量。然后,通过为 frobChecker 结构体定义相应的方法,可以在不将这些函数作为 frob 的方法的情况下,对 frob 进行各种检查。在 doChecks 函数中,通过创建 frobChecker 的实例 fc,并将 frob 作为参数传递给它,可以使用 fc 来调用各种检查函数。

英文:

You could do something like this to avoid having to explicitly pass frob over and over, while still being able to avoid making those functions methods on frob.

type frobChecker struct {
    frob some.Frob
}

func (fc frobChecker) discountLimit(maxDiscount float64) (RuleStatus, string) 
func (fc frobChecker) discountPercentageLimit(maxDiscountPercentage float64) (RuleStatus, string) 
func (fc frobChecker) usageLimit(interval valueInterval) (RuleStatus, string) 
func (fc frobChecker) permanentExpiryLimit() (RuleStatus, string) 
func (fc frobChecker) voucherValidity(maxValidityDays uint) (RuleStatus, string) 

func doChecks(frob some.Frob) {
    fc := frobChcker{frob}

    status, message := fc.discountLimit(100)

    if status != PASSED {
       ....
    }

    ... evaluate all remaining rules here ...
}

huangapple
  • 本文由 发表于 2017年7月10日 16:22:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/45007100.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定