コンテンツにスキップ

英文维基 | 中文维基 | 日文维基 | 草榴社区

「Mixin」の版間の差分

出典: フリー百科事典『ウィキペディア(Wikipedia)』
削除された内容 追加された内容
編集の要約なし
Cewbot (会話 | 投稿記録)
m Bot作業依頼: sourceタグをsyntaxhighlightタグに置換 (Category:非推奨のsourceタグを使用しているページ) - log
49行目: 49行目:
Python の、特に Python 2.3 以降および Python 3 では C3 linearization により多重継承した際のメソッド探索順は解決されるので、多重継承は有力な手法であり、実際にいくつか活用例がある。<code>SocketServer</code> モジュールは [[User Datagram Protocol|UDP]] および [[Transmission Control Protocol|TCP]] ソケットサーバとして動作する <code>UDPServer</code> と <code>TCPServer</code> クラスの両方を備えている。通常、すべてのコネクションは同じプロセス内で処理されるが、<code>ForkingMixIn</code> と <code>ThreadingMixIn</code> という追加の mixin クラスが存在する。下記のように TCPServer を ThreadingMixIn により拡張すると、
Python の、特に Python 2.3 以降および Python 3 では C3 linearization により多重継承した際のメソッド探索順は解決されるので、多重継承は有力な手法であり、実際にいくつか活用例がある。<code>SocketServer</code> モジュールは [[User Datagram Protocol|UDP]] および [[Transmission Control Protocol|TCP]] ソケットサーバとして動作する <code>UDPServer</code> と <code>TCPServer</code> クラスの両方を備えている。通常、すべてのコネクションは同じプロセス内で処理されるが、<code>ForkingMixIn</code> と <code>ThreadingMixIn</code> という追加の mixin クラスが存在する。下記のように TCPServer を ThreadingMixIn により拡張すると、


<source lang="python">
<syntaxhighlight lang="python">
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
pass
pass
</syntaxhighlight>
</source>


<code>ThreadingMixIn</code> が <code>TCPServer</code> にコネクションごとに[[スレッド (コンピュータ)|スレッド]]を生成する機能を追加する。あるいは、<code>ForkingMixIn</code> を用いると各新規のコネクションに対してプロセスが fork される。明らかに、スレッドを生成したりプロセスを fork する機能は単独では大して役に立たない。
<code>ThreadingMixIn</code> が <code>TCPServer</code> にコネクションごとに[[スレッド (コンピュータ)|スレッド]]を生成する機能を追加する。あるいは、<code>ForkingMixIn</code> を用いると各新規のコネクションに対してプロセスが fork される。明らかに、スレッドを生成したりプロセスを fork する機能は単独では大して役に立たない。
62行目: 62行目:
[[C Sharp|C#]]では[[インタフェース (抽象型)|インタフェース]]<!-- マイクロソフトの日本語ドキュメントでは「インターフェイス」だが、この記事では「インタフェース」に統一している。 -->と拡張メソッドの組合せによって、Mix-inを再現できる。
[[C Sharp|C#]]では[[インタフェース (抽象型)|インタフェース]]<!-- マイクロソフトの日本語ドキュメントでは「インターフェイス」だが、この記事では「インタフェース」に統一している。 -->と拡張メソッドの組合せによって、Mix-inを再現できる。


<source lang="csharp">
<syntaxhighlight lang="csharp">
using System.Linq;
using System.Linq;


72行目: 72行目:
// 上記は下記の糖衣構文である。
// 上記は下記の糖衣構文である。
int sum = Enumerable.Sum(range);
int sum = Enumerable.Sum(range);
</syntaxhighlight>
</source>


== 関連項目 ==
== 関連項目 ==

2020年7月5日 (日) 22:57時点における版

mixin とはオブジェクト指向プログラミング言語において、サブクラスによって継承されることにより機能を提供し、単体で動作することを意図しないクラスである。言語によっては、その言語でクラスや継承と呼ぶものとは別のシステムとして mixin がある場合もある(#バリエーションの節で詳述)。

概要

オブジェクト指向プログラミングにおいて、継承は本来は特化を意図したものである。すなわち、継承する側(派生型)と継承される側(基底型)の間にはリスコフの置換原則があることを前提とする。

しかし実際のところは、実装の再利用のための手段として使われることが多い(濫用されがちであるが)。mixin における継承も、前述のような特化のためではなく、複数の機能を集めるための手段である。特にクラスの多重継承が可能なシステムでは、複数の mixin クラスを多重継承し、「単に複数の機能を持つクラス」を簡単に作る、というような使い方ができる。典型例としては、InputStream と OutputStream という mixin クラスを多重継承して、InputOutputStream という双方向ストリームのクラスとする、といったようなパターンである。

mixin は、そのようなもの自体はそれ以前からも考えられていたが、シンボリックス社のオブジェクト指向システム Flavors(en:Flavors (programming language))でその名が使われ、それが一般化した。Flavorsは、同社のLispマシンにおける、同時期にいくつかあった、Lispでの、あるいはLispによるオブジェクト指向の試みのひとつである。名称の由来は、マサチューセッツ州 Somerville にあったアイスクリーム屋[1]からヒントを得て考え出されたものであった[2](シンボリックス社は「MIT発のベンチャー」のひとつである)。このアイスクリーム店の店長は(バニラやチョコレートなどの)基本となる味を混ぜ、追加の具材(ナッツ、クッキー、キャンディなど)と組み合わせたものを提供し、それを Mix-In と呼んで店の登録商標としていた[3]

mixin はコードの再利用を促進する。しかし、mixin にはそれなりの妥協も伴う。

(クラスの多重継承すなわち実装の多重継承ができず、インタフェースの複数実装による型の多重継承のみができる、例えばJavaC#などの観点からは)mixin は、「メソッド実装付きのインタフェース」ということもできる。クラスが mixin を含む場合、そのインタフェースを実装したクラスは、mixin の属性と操作を取り込む。継承するというのとは異なっている。取り込んだ要素はコンパイル時にクラスの一部となる。興味深いことに、mixin はインタフェースを実装する必要はない。それでもあえてインタフェースを実装する利点は、そのインタフェースを必要とするメソッドに、引数としてインスタンスを渡せるからである。

バリエーション

クラスとその継承関係とは別のものとして mixin を活用している言語としてRubyがある。Rubyではクラスの継承は単一継承のみとし、多重継承にまつわる問題(例えば菱形継承問題)を避けた。そして「継承関係の無いクラスのようなもの」としてモジュールと呼ばれる言語機能があり、モジュールは複数個(いくつでも)クラスに「mixinする」ことができる。モジュール自体は何かを継承したりはしていないため、菱形継承問題は起きない。

その他、mixinのようなものがある言語。

Python

Python の、特に Python 2.3 以降および Python 3 では C3 linearization により多重継承した際のメソッド探索順は解決されるので、多重継承は有力な手法であり、実際にいくつか活用例がある。SocketServer モジュールは UDP および TCP ソケットサーバとして動作する UDPServerTCPServer クラスの両方を備えている。通常、すべてのコネクションは同じプロセス内で処理されるが、ForkingMixInThreadingMixIn という追加の mixin クラスが存在する。下記のように TCPServer を ThreadingMixIn により拡張すると、

class ThreadingTCPServer(ThreadingMixIn, TCPServer):
  pass

ThreadingMixInTCPServer にコネクションごとにスレッドを生成する機能を追加する。あるいは、ForkingMixIn を用いると各新規のコネクションに対してプロセスが fork される。明らかに、スレッドを生成したりプロセスを fork する機能は単独では大して役に立たない。

この使用例では、mixin はソケットサーバとしての機能に影響することなく、基盤となる機能を選択可能な形で提供している。

C#

C#ではインタフェースと拡張メソッドの組合せによって、Mix-inを再現できる。

using System.Linq;

  System.Collections.Generic.IEnumerable<int> range = Enumerable.Range(1, 10);
  // IEnumerable<T>にはSum()メソッドは定義されない。
  // 実際にはSystem.Linq.Enumerableクラスに実装された拡張メソッドである。
  int sum = range.Sum();

  // 上記は下記の糖衣構文である。
  int sum = Enumerable.Sum(range);

関連項目

  1. ^ Steve's Ice Cream Parlor
  2. ^ Using Mix-ins with Python
  3. ^ LISTSERV 14.4

外部リンク