ひよっこ。

I want to…

Flex3におけるMixinに関して

Posted by hikaruworld : 2009 8月 23

FlexAutomationAPIを理解していく上でMixin(Mix-in)という概念を理解しておく必要があるようなので、
どういった物か調べていました。

自分の脳みそを整理するために書いているので、
もし間違っていたら突っ込んでいただけると感謝します。

なお、Mix-inの公式ドキュメントとしては、古いですがMacromedia FlexDocumentation Mix-inの利用が参考になると思います。
上記から抜粋になりますが、オブジェクト指向におけるMix-inの概要は以下のように説明されています。
あとは、Rubyのまつもとさんがこの概念を説明されているのでそちらの方がより参考になるでしょう。
RubyではMix-inがサポートされているんですね、知りませんでしたorz…

Mix-in は、継承を使用せず、動的に既存クラスのメソッドをカスタムクラスに追加するための簡単な手段です。クラスを Mix-in することで、既存クラスのメンバーを、カスタムクラスのプロトタイプオブジェクトに追加できます。ActionScript では多重継承がサポートされていませんが、Mix-in を使用すれば、他の Flex クラスを継承してカスタムクラスを作成する通常の方法では使用できない機能をカスタムクラスに追加できます。

オブジェクト指向言語における Mix-in とは、他のクラスに機能を追加するために使用される最小限のユニットです

わかるようなわからないような表現です。。。

Flexにおいては、仕様の継承はinterfaceを用いて多重継承することが可能ですが、
機能の継承は単体継承のみで言語仕様上多重継承がサポートされていません。
そのかわりと言っては何ですが多重継承の代替手段的にMix-inという概念が組み込まれているようです。
(Mixin自体は多重継承のテクニックの一つらしいですが、それを言語上非公式にサポートしている事になります。)

実際には、この方法を用いて、Flexアプリケーション起動時にMixin対象クラスに対してinit()メソッドを実行し、
内部で任意の実装(機能)を「織り込む」ことが出来るようになります。
(ただし、initメソッドはpublic staticである必要があるため、自身以外のインスタンスを操作する事は出来ません)

Flex自身によって提供されている[Mixin]は、AutomationAPIを例にして考えると、
「Flexコンポーネントクラス」に「オートメーション」という機能をMix-inする事で
Flexオートメーションフレームワークを実現していることになると理解しました。

さて、Flexで具体的なMixinの実装方法は以下の様に行います。

  1. 特定のクラスに対してメタタグ[Mixin]を使いMixin対象である事を指定します。
  2. 上記クラスにpublic static function init(st:SystemManager):voidというメソッドを定義します。
  3. コンパイル時に、明示的にコンパイル対象クラスである事を指定して
    (Flexでは、プログラム上利用されないクラスはコンパイル対象にならないためです)コンパイルを行います。
    • ※コンパイル対象に指定する方法は、どこかに宣言を書くか、コンパイル引数として対象クラスを渡す必要があります。

上記の手順を踏むと、SystemManagerのdocFrameHandler()内部で
MIxinされたクラスのinitのメソッドが実行されます。

# docFrameHandler()はFlashのタイムラインで言う2フレーム目に進んだタイミングで実行されます。
# なお、通常Flexの開発者によって定義された起動クラスは2フレーム目に配置されることになります。

SystemManagerの実装は以下のような感じになっていました。

var mixinList:Array = info()["mixins"];
if (mixinList && mixinList.length > 0)
{
    var n:int = mixinList.length;
    for (var i:int = 0; i < n; ++i)
    {
        // trace("initializing mixin " + mixinList&#91;i&#93;);
        var c:Class = Class(getDefinitionByName(mixinList&#91;i&#93;));
        c&#91;"init"&#93;(this);
    }
}
&#91;/sourcecode&#93;
info()と言うメソッドでmixinsというプロパティ群を取得後、
getDefinitionByNameでクラスを取得し自身を引数としてinitメソッドを実行しています。
このinfo()メソッドはSystemManagerクラス上では以下のような空実装になっています。
&#91;sourcecode language='javascript'&#93;
/**
 *  @private
*/
public function info():Object
{
    return {};
}
&#91;/sourcecode&#93;
このinfo()メソッドは、コンパイル時にMXMLの起動クラスから自動生成された
asクラスの指定先のsystemManagerによってoverrideされたものが参照されるそうです。

HelloWorld文字列を表示するような単純なAirアプリでは、
コンパイル時に生成される_Sample_mx_managers_SystemManagerのoverride部分は以下のようになっていました。
※コンパイラオプションに<em>--keep</em>を指定してコンパイルするとソースファイル以下に
  generatedというディレクトリができMXMLから生成されたASファイルを参照できます。

override    public function info():Object
{
    return {
    compiledLocales: [ "ja_JP" ],
    compiledResourceBundleNames: [ "collections", "containers", "controls", "core", "effects", "skins", "styles" ],
    currentDomain: ApplicationDomain.currentDomain,
    layout: "absolute",
    mainClassName: "Sample",
    mixins: [ "_Sample_FlexInit", "_macMinButtonStyle", "_alertButtonStyleStyle", "_ControlBarStyle", "_ScrollBarStyle", "_winMaxButtonStyle", "_activeTabStyleStyle", "_textAreaHScrollBarStyleStyle", "_ToolTipStyle", "_winCloseButtonStyle", "_DragManagerStyle", "_macCloseButtonStyle", "_statusTextStyleStyle", "_advancedDataGridStylesStyle", "_WindowedApplicationStyle", "_gripperSkinStyle", "_comboDropdownStyle", "_winRestoreButtonStyle", "_HTMLStyle", "_textAreaVScrollBarStyleStyle", "_ContainerStyle", "_globalStyle", "_linkButtonStyleStyle", "_windowStatusStyle", "_windowStylesStyle", "_PanelStyle", "_activeButtonStyleStyle", "_WindowStyle", "_errorTipStyle", "_richTextEditorTextAreaStyleStyle", "_todayStyleStyle", "_CursorManagerStyle", "_dateFieldPopupStyle", "_plainStyle", "_dataGridStylesStyle", "_winMinButtonStyle", "_macMaxButtonStyle", "_ApplicationStyle", "_headerDateTextStyle", "_ButtonStyle", "_popUpMenuStyle", "_titleTextStyleStyle", "_AlertStyle", "_swatchPanelTextFieldStyle", "_opaquePanelStyle", "_weekDayStyleStyle", "_headerDragProxyStyleStyle" ]
    }
}

[Mixin]というメタタグを付与すると、このmixinsにクラス名が格納される事になり、
この配列に格納されている場合に、Mixin処理が行われるという事になるようです。

しかし、これらのことから「Flexは非公式ではあるがMixin型の多重継承をサポートしている」と
言ってしまってよいのかどうなのかその辺りがやっぱりよくわかりませんでした。

コメント / トラックバック2件 to “Flex3におけるMixinに関して”

  1. coelacanth said

    こんな機能があったのですね。
    勉強になりました。
    メタタグとか全然理解してない・・・

  2. prepro said

    > coelacanth さん
    理解があっているかどうか自信ないっすけどねー。
    メタタグは非公式が実は色々あるんですよ。

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

 
%d人のブロガーが「いいね」をつけました。