2012-01-08 21 views
0

質問は少し愚かです。スキル更新システムを実装しようとしています。それで説明する。クラスへの参照を別のクラスに渡す方法

静的変数のいずれかに基準を取る必要があり、クラス

class AppInfo 
{ 
    public static var power:int = 10; 
    public static var speed:int = 20; 

} 

クラスSmartButtonがあり、例えばコンストラクタでパワーアップし、与えられた値でそれをインクリメントします。

class SmartButton 
{ 
    public function onClick(skillReference:int = <AppInfo.power>, incrementVAlue:int = 10) 
    { 
     skillReference += incrementVAlue 

    } 

} 

このコードでは、このコードでAppInfoクラスの消費電力値を更新します。しかし、これは起こらない...私はスキルが参考として値として渡されたためだと思う...

あなたはタスクを解決する方法を提案できますか?

おかげ

答えて

2

あなたの前提は正しく、intsは参照ではなく値渡しとなります。一つの直接的なアプローチは、参照型(class)よりもむしろ値型に電源をカプセル化することであろう。

class Skill { 
    public var value:int; 

    public function Skill(val:int) { 
     this.value = val; 
    } 
} 

class AppInfo 
{ 
    public static var power:Skill = new Skill(10); 
    public static var speed:Skill = new Skill(20); 

} 

そしてpowerを通過するインスタンスへの参照として渡す必要があります。代わりにskillReference.valueを使用するためにあなたの実装を少し変更する必要がありますが。

それ以外にも、あなたが望むものを抽象化する方法がいくつかあると思います。 1つの方法は、インターフェースを使用し、依存性注入を活用することです。

interface ISkills 
{ 
    function get power():int; 
    function set power(val:int):void; 
} 

class AppInfo implements ISkills 
{ 
    private static _power:int = 0; 

    public function get power():int { return _power; } 
    public function set power(val:int):void { _power = val; } 
} 

class SmartButton 
{ 
    public function onClick(skills:int = ISkills, skill:String = "power", incrementVAlue:int = 10) 
    { 
     skills[skill] += incrementVAlue 
    } 
} 

ここでは、使用方法を実装から切り離したいと考えています。この場合、SmartButtonは、スキルがどのように操作するのかを知る必要はありません。これは、静的クラスAppInfoへの参照を、注入可能なインスタンスのために失います。このアプローチにはいくつかの利点があります。クラスやコードを更新することなく、静的クラスが最良の実装方法ではないと判断した場合は、テストを簡単にし、実装を簡単にスワップしやすくなります。また、メソッドにISkillsを注入するのではなく、SmartButtonのコンストラクタに注入して、スキルコンテナへの参照を保持しておいてください(private)。

もう1つのアプローチは、機能的アプローチを使用することです。

class SmartButton 
{ 
    public var defaultWorker:Function = function(val:int):void { 
     AppInfo.power += val; 
    } 

    public function onClick(worker:Function = undefined, incrementValue:int = 10):void 
    { 
     if(worker == undefined) worker = defaultWorker; 
     worker.call(this, incrementValue); 
    } 
} 

繰り返しますが、この場合には、かなりしっかりと直接AppInfoクラスを使用するように実装を結合するよりも、あなたはそれのための「労働者」を注入し、作業者がundefinedデフォルトの労働者を使用している場合(あなたのための作業を行います渡されたクロージャーを変更することによって、どのプロパティーが変更されるかを交換することができます。それができるよう

var smartButton:SmartButton; 
smartButton.onClick(function(val:int):void { AppInfo.speed += val}); 

ほど簡潔ではないが、それは仕事を取得します。あなたの代わりにspeedを変更したい場合たとえば、あなたは呼ぶだろう。 command patternを使用して

0

私はおそらく少し異なる方法でこれを実装します。

多分次のようなものです。

class Properties { 
private var _properties:Dictionary = new Dictionary(); 

    public function setValue(key:String, value:int) { 
     _properties[key] = value; 
    } 

    public function getValue(key:String):int { 
     if(!_properties[key]) return 0; 
     else return _properties[key]; 
    } 

    public function modifyValue(key:String, value:int) { 
     setValue(key, getValue(key) + value); 
    } 
} 

class SmartButton 
{ 
    public function onClick(target:Properties, key:String, incrementValue:int = 10) { 
     target.modifyValue(key, incrementValue); 
    } 
} 

またはこれらの行に沿ったもの。

1

義務 "エレガントな洗練された" アプローチ:

Interface Command { 
    function execute():void; 
} 

Class UpdatePower implements Command { 
    private var appInfo:AppInfo; 
    private var delta:int; 

    public function UpdatePower(appInfo:AppInfo, delta:int) { 
     this.appInfo = appInfo; 
     this.delta = delta; 
    } 

    public function execute():void { 
     appInfo.delta += delta; 
    } 
} 

Class SmartButton { 
    var command:Command; 

    public function SmartButton(command:Command) { 
     this.command = command; 
    } 

    public function onClick(event:Event):void { 
     command.execute(); 
    } 
} 
関連する問題