3

私は、FlashとのOOP関連の問題を持っています。これは個人的なプロジェクトで、私はこの問題のデザインパターンや回避策を探しています。目標は新しいものを学ぶことです。OOPの問題:クラスを拡張し、関数とjQueryのような構文をオーバーライドする

私はChainというクラスを作成しました。私はこの関数を作成し、遅延関数呼び出しを容易にしました。ミリ秒単位の遅延を加えて、一連の関数を作成することができます。このチェーンは、逆の順序でも複数回実行できます。このクラスには、それ自身を返す関数があります。私は、問題を実証するための機能の多くを残している。例えば

var chain:Chain = new Chain(); 
chain.wait(100).add(myFunction1,300).wait(300).add(myFunction2,100); 
// etc.. 

:それはjQueryのは、このような構文を持つスタイリングすることが可能となります。 Chainクラスは、関数を追加し、チェーンを開始/停止するためにほとんど純粋です。

public class Chain 
{ 
function wait(delay:int = 0):Chain 
{ 
    // do stuff 
    return this; 
} 

public function add(func:Function, delay:Number = 0):Chain 
{ 
     list.push(new ChainItem(func, delay)); 
     return this; 
} 
} 

今、別のクラスのChainTweenがあります。私はいくつかのコア機能を持つチェーンを維持するために物事を分割しようとしているし、ChainTweenはいくつかのアニメーションのトリックをしています。私はChainクラスに基づいて小さなツインエンジンを作るという考えがありました。現在はChainを拡張しています。これはChainクラスの多くの保護された変数を使用し、チェーンのプロセス内にトゥイーン関数を追加するためのChainのいくつかのコア関数をオーバーライドします。

public class ChainTween extends Chain 
{ 
function animate(properties:Object = null, duration:Number = 0, easing:Function = null):ChainTween 
{ 
    // do stuff 
    return this; 
} 
} 

は今、これは問題です:私は()チェーンのインスタンスを返す連鎖構文を保つが、待ちたいとチェーンにはアニメーション機能を持っていません。

var chain:ChainTween = new ChainTween(); 
chain.wait(100).animate({x:200}, 100).wait(250); 

私はChainTweenクラスでwait()関数とadd()関数をオーバーライドしようとしましたが、互換性のないオーバーライドが発生します。

私はChainTweenとしてchain.wait(100)をキャストすることができましたが、これは非常に醜いものであり、たくさん連鎖しているときは役に立たないです。 ChainTween関数をChainに追加したくないので(ダミー関数もありません)、すべての関数を補完したいので、Objectを返すこともオプションではありません。私はインターフェイスを使用しようとしましたが、インターフェイスの機能はそれを実装するクラスで実装する必要があるため、同じ問題が発生します。

ChainTween内でChainのインスタンスを作成することを考えましたが、これで関数をオーバーライドすることはできません。次に、protectedの代わりにたくさんのプロパティをpublicにする必要があります。

これは可能ですか?これには誰かが素晴らしい解決策を持っていますか?

答えて

2

この問題はかなり一般的です。あなたが使っているデザインパターンはFluent Interfaceと呼ばれています.Googleの「Fluent Interface Inheritance」では、たくさんの質問やごく少数の回答があります。

C#、JavaおよびC++ is to use templatesで解決する一般的な方法です。しかし、私はAS3で同じものを実装する方法を伝えることはできません、私はthis topicあなたを助けるかもしれないとわかりました。

+0

ありがとうございましたこの回答は非常に解決策を見つけるのに役立ちます。 –

1

機能をコード補完で表示するには、コード補完が必要です。これは、実行時の検出方法を排除します。私はチェーンに以下のようなものを追加します:

public function animate(args:Object, time:int):Chain { 
    throw new Error("Animate is supported only on ChainTween"); 
} 

はChainTweenで上書きされます。それほど大きなストレッチだとは思わないでください。

+0

これは10個のトゥイーン関数がある場合、すべてをチェーンクラスに追加する必要があることを意味しますか?これは、Chainクラスに、元の '関数'とは何の関係もないたくさんの関数を与えます。もう一つの解決策があることを願っています。 –

+0

JQueryはこれを行うことができますが、コード補完はありません...すべての要件を満たす方法はわかりませんが、ここでは何かを犠牲にしなければなりません。 – alxx

0

チェーンの代わりに*を返すこともできますが、コードヒントは削除されます。鎖クラスの構造に続い

+0

真実ですが、これは私が望むものではありません。私は+コードヒントを欲しいと思っています:) –

+1

alxxが提案したもの以外にもこれを行う方法は他にありません。フラッシュIDEにそのような魔法の機能があるとは言えません。強い型付けされた言語の原則。私は全体的なアイデアが好きです:)。 – Maurycy

0

私はあなただった私が唯一のコア機能(addwaitなど)を記述するIChainインターフェースを作成したい場合

+0

はい、どうしますか?すべての関数はChainの代わりにIChainを返すべきですか?私はこれを試しましたが、chain.wait()。animate()を実行するとエラーが発生します。これはアニメーションがIChainインターフェイスにないからです。 IChainにすべての関数を追加すると、元のChainクラスにすべてのインターフェイス関数が含まれている必要があります。次に、Chainがtween関数を実装する必要があります。これは好ましくありません。 これは複数のインターフェイスで可能かもしれませんか? –

+0

@マークKnol:あなたが 'instance.animate()'を呼んでいる場合、 'instance'が' ChainTween'であることを知っていることを意味します - imho 'IChain'はコア関数のみを必要とし、' extended '関数へのアクセスは – www0z0k

+0

はい、私は知っていますが、ドキュメントや他の人の中でこれを説明するのは非常に難しいでしょう。これは、私が簡単なコーディングスタイルを破るためです。使用しようとしている。それは本当にオプションではありません。 –

1

、それはアドオンを使用することが可能(と何とか論理)でなければなりませんアニメーションメソッドを呼び出すメソッド...Chainクラスの詳細がわからないほど、正確にするのは難しいですが、理論的には可能性があります。addメソッドに新しい引数を追加する必要があります。

var chain:ChainTween = new ChainTween(); 
var params:Object = {x:200}; 
chain.wait(100).add(animate, 300 , params).wait(300); 

alxxはポイントを持って、それが何かはJavascriptとは異なり、AS3は強く型付けされた言語であり、何らかの形で与えることがあるように思わ、これはあなたの限界の非常に原因です。 rotate、fadeOutなどの特定のメソッドを実装する必要がある場合は、たくさんのソリューションを用意する必要はありません。これらのメソッドはChainTween、Chain、Objectのいずれかを返し、Objectと*の両方を破棄します。

どういうわけか、私はまだrotate、fadeOut、またはanimateメソッドをadd()(またはその目的のために作成することができる他の方法もあります)は、チェーンのデザインと一層合致しています。

+0

はい、あなたは正しいですが、これは内部的に少し複雑です。どのように動作するのか、show()、hide()、fadeIn()、fadeOut()、rotate()、move()、animate()のような素早い関数を作成したい。連鎖可能である。 –

0

私はすでに提案されているインターフェイスのアイデアに行きます。 「IChainTween」のようなものが返されるのは、ChainTweenを構成するメソッドだけでなく、元のChainを返す「then」のような関数も含まれます。

package 
{ 
    public interface IChainTween 
    { 
     function doSomething():IChainTween; 
     ... 
     function then():IChain; 
    } 
} 

package 
{ 
    public class ChainTween implements IChainTween 
    { 
     private originalChain:IChain; 
     public function ChainTween(IChain chain) 
     { 
      originalChain = chain; 
     } 
     ... 
     public function doSomething():IChainTween 
     { 
      return this; 
     } 
     public function then():IChain 
     { 
      return originalChain; 
     } 
    } 
}