2010-04-08 60 views
26

我经常发现自己创建它使用这种形式(A)类:命名约定非虚拟和抽象方法

abstract class Animal { 
    public void Walk() { 
    // TODO: do something before walking 

    // custom logic implemented by each subclass 
    WalkInternal(); 

    // TODO: do something after walking 
    } 
    protected abstract void WalkInternal(); 
} 

class Dog : Animal { 
    protected override void WalkInternal() { 
    // TODO: walk with 4 legs 
    } 
} 

class Bird : Animal { 
    protected override void WalkInternal() { 
    // TODO: walk with 2 legs 
    } 
} 

而不是这样的形式(B):

abstract class Animal { 
    public abstract void Walk(); 
} 

class Dog : Animal { 
    public override void Walk() { 
    // TODO: do something before walking 

    // custom logic implemented by each subclass 
    // TODO: walk with 4 legs 

    // TODO: do something after walking 
    } 
} 

class Bird : Animal { 
    public override void Walk() { 
    // TODO: do something before walking 

    // custom logic implemented by each subclass 
    // TODO: walk with 2 legs 

    // TODO: do something after walking 
    } 
} 

正如你可以看到,形式A的好处在于,每次实现子类时,都不需要记住包含初始化和终结逻辑。这比形式B更不容易出错。

什么是命名这些方法的标准惯例?
我喜欢命名公共方法Walk,因为我可以打电话Dog.Walk(),这比Dog.WalkExternal()好看。但是,我不喜欢我为受保护的方法添加后缀“Internal”的解决方案。我在寻找更加标准化的名字。

顺便说一句,有这个设计模式的名称?

+0

好问题;我也一直这样做。 – 2010-04-08 04:56:29

+0

@罗伯特:你在调用什么内部方法? – Senseful 2010-04-08 05:06:04

+0

Impl在WalkImpl ....没有比内部更好。 – 2010-04-08 05:54:00

回答

11

我不是确定是否有一个标准的命名约定。除了WalkInternal,其他替代品可能是DoWalkWalkImpl

+0

另外我看到的是* MakeWalk * – Leyu 2013-05-09 07:51:52

-2

方法是采取行动的手段,并遵循该规则方法名称应该是动词或动词短语。它适用于方法,而不管它们在何处声明。对我来说Dog.Walk看起来比Dog.WalkInternal更自然。方法的命名比设计模式更具指导性:)如果你是一个.Net人,那么我会推荐Brad Adam和Krzystof Cwalina的“Framework Design GuideLines”一书,它清楚地解决了这些问题。

+1

这是如何解决具体问题的。如果“WalkInternal”不好,那么*好*是什么? – 2010-04-08 04:57:25

+0

问题不是Dog.Walk()vs Dog.WalkInternal()。我想将暴露的方法称为“漫步”,因为像你说的那样,它看起来更自然。问题在于每次调用Walk()方法时,调用这个内部方法来处理每个子类的主定制逻辑。但感谢您的答案。 – Senseful 2010-04-08 05:03:27

+0

由于内部方法对外部世界不可见,因此可以根据您的偏好命名它。在某些地方我注意到的是,在方法名称后面加上“Helper”字样的方法。在这种情况下,您的“WalkInternal “将成为”WalkHelper“。 – 2010-04-08 05:26:35

10

顺便说一句,有没有这个设计模式的名称?

你的第一个例子使用了模板方法模式的方面是类似于香草萨特所说的“非虚拟接口成语”:

+0

这与我所指的设计模式完全相同。对于其他感兴趣的人,Herb Sutter使用前缀“Do”作为内部方法(例如DoWalk()而不是WalkInternal())。而且,他推荐这种形式的另一个原因是将接口和实现的关注分开。 – Senseful 2010-04-08 17:53:16

3

好问题。该模式是有效的,我使用它很多。我也同意WalkInternal不是一个理想的名字。

在这个例子中,我相信你没有正确地解决问题。

而不是重命名'内部'方法,看看你'外部'的公共方法。它被称为Walk,但它有代码片段(//do something before walking//do something after walking),清楚地表明它包含的不仅仅是“走路”的逻辑。也许这种方法应该被称为ExerciseGoToTheShops - 或者你可以想到的任何创意名称都描述了你正在做的事情。无论采取什么方法,它绝对是散步+其他一些前/后步行动作的超集。

一个类似的例子,我最近开发了一个公共方法叫Complete和虚拟叫Save,使:

  • 需要“完成”每类
  • 不同的实现将有自己的自己的“保存”方法
  • “完成”也将进行一些验证,通知等

综上所述,抽象的我的ThOD应该叫Walk,而是你应该重命名的公共方法的东西,更准确地描述了“做一些事情/行走/做些什么”的过程。


编辑:如果Walk类没有任何显著值或逻辑添加到WalkInternal类,然后我会质疑它是否是必需的。如果它添加了逻辑,那么它应该重新命名以反映它的新功能。

8

我宁愿名加上Core我的虚拟或抽象方法,以表明,该方法应该包含核心逻辑,做一些事情。

所有参数的检查和提高可能发生的事件我做的方法,调用核心的方法。

abstract class Animal { 
    public void Walk() { 
     // TODO: do something before walking 
     // possible Argument checks and event raising 

     // custom logic implemented by each subclass 
     WalkCore(); 

     // TODO: do something after walking 
    } 

    protected abstract void WalkCore(); 
    } 

    class Dog : Animal { 
    protected override void WalkCore() { 
     // TODO: walk with 4 legs 
    } 
    } 

    class Bird : Animal { 
    protected override void WalkCore() { 
     // TODO: walk with 2 legs 
    } 
    } 

我认为这没有官方的命名准则,这取决于你。但是它应该对您定义的所有类和虚拟/抽象方法保持一致。

如果您遵循模板方法并希望提供可扩展性点,则"Framework Design Guidelines"建议使用核心后缀。

+0

+1为“框架设计指南”的参考。 – 2012-02-15 16:21:30

2

我用抽象的覆盖下划线资本案件的惯例,那么Dog._Walk,虽然我比偶尔不知道是否有更好的方法没有。

我喜欢DoWalk比WalkInternal更好 - 它是短&传达的想法,它的覆盖迅速和前期。 “做什么”尽管有点像我的“物体”那样,但我仍然错误地使用了它。我仍然喜欢我的下划线,然后是大写字母惯例。

好现实生活中的问题,虽然

干杯,
Berryl

0

对于提供了一个模板方法的主要行为的方法,我用的名字,如WalkOverride。基类将其作为protected abstract方法(派生类为需要来提供实现)或protected virtual空/非空(其派生类可能可选地提供/覆盖实现)来实现它。实例可以在微软的XAML各种与框架的方法,如MeasureOverrideArrangeOverride被发现。 (@Jehof提到的WalkCore模式在那里用于命名模板方法本身。)

对“事件”给其派生类可以有选择地响应达到自己的目的(而不是定义模板方法的行为),我使用像OnWalkingOnWalked名。这些方法中的每一个通常都在基类中作为具有空方法体的protected virtual方法实现。