从对象中提取行为

时间:2014-10-18 17:12:36

标签: oop design-patterns architecture language-agnostic

我有一个成为God Object的班级。在这个游戏中,它管理主要的游戏场景本身,这应该是它变得如此大的原因。

但是我可以将这个课程的某些部分组合在一起。具体来说,他们处理一种在游戏中随机触发的特殊模式。

我想知道将这种行为分开并将其转换为Object的最佳方法是什么。我迷失在这里,因为这是一种行为,而不是一种"因此我无法想到一个美好而优雅的解决方案。

class Game
    var lives = 1
    var score = 0
    var time = 0

    doStuff() {}
    doMoreStuff() {}
    specialActivate() {}
    specialUpdate() {}
    specialInput() {}
    specialDeactivate() {}

正如您所看到的,有许多特殊模式"相关功能。问题是这些函数中的一些依赖于Game中包含的变量和方法。

  1. 创建一个新类,并在Context(或Model)对象中一起发送所需的变量和回调。

    class Game
        var lives = 1
        var score = 0
        var time = 0
        var special = new Special(new SpecialContext(lives, score, time, doStuff))
    
        doStuff() {}
        doMoreStuff() {}
    
    class Special
        var context:SpecialContext
    
        constructor(context:SpecialContext)
            this.context = context
    
        activate() {}
        deactivate() {}
        input() {}
        update() {}
    
    class SpecialContext
        var lives
        var score
        var time
        var doStuff:Callback
    
        constructor(lives, score, time, callbackDoStuff:Callback)
            this.lives = lives
            this.score = score
            this.time = time
            this.doStuff = callbackDoStuff
    
  2. 创建一个界面并让Game实现该界面,以保护游戏。

    class Game implements IGameSpecial
        var lives = 1
        var score = 0
        var time = 0
        var special = new Special(this)
    
        doStuff() {}
        doMoreStuff() {}
    
    class Special
        var game:IGameSpecial
    
        constructor(gameSpecial:IGameSpecial)
            this.game = game
    
        activate() {}
        deactivate() {}
        input() {}
        update() {}
    
    interface IGameSpecial
        doStuff()
        getLives()
        setLives()
        getTime()
        setTime()
        getScore()
        setScore()
    
  3. 直接发送游戏类(脏方法)。

    class Game
        var lives = 1
        var score = 0
        var time = 0
        var special = new Special(this)
    
        doStuff() {}
        doMoreStuff() {}
    
    class Special
        var game:Game
    
        constructor(gameSpecial:Game)
            this.game = game
    
        activate() {}
        deactivate() {}
        input() {}
        update() {}
    
  4. 有一种优雅的方法来解决这个问题吗?此问题是否具有与之关联的名称或模式?

2 个答案:

答案 0 :(得分:2)

你提到了一种“特殊模式”,大概是与“正常模式”相对立的。 “模式”是(或至少可以是)一种类型,它建议使用状态模式。但是,看起来你在类中没有任何类型的代码来判断是否应该使用这些“特殊”方法,所以我假设在类之外还有一些决定它的东西。

我希望您可以将“特殊”方法分解为Game类中更简单的方法。这意味着你可以让“特殊模式”成为在适当的时候应用于游戏的装饰器。这是否有效取决于Game类的使用方式。

答案 1 :(得分:1)

我会这样做:

1)创建一个界面:

interface ISpecialAction {
    execute()
}

2)为每个特殊行动实施它:

class Activation implements ISpecialAction {
    setLives()
    setTime()
    execute()
}

3)将班级游戏委托给这个班级

class Game {

    specialActivate() {
         Activation a = new Activation()
         a.execute()
    }

}

这将特殊操作与Game类分离,所以 在特殊的事情上,你不会再有上帝的课了 动作。 特殊操作类实现的接口可以提供帮助 例如,当使用Factory或Builder创建时 特别行动。