集約
日本語 | 集約 |
英語 | aggregation |
ふりがな | しゅうやく |
フリガナ | シュウヤク |
あるクラスの機能を持つクラスのこと。
特定のクラスの機能を、自分が作るクラスにも持たせたい場合に、継承を使わずフィールドとしてそのクラスを持ち、そのクラスのメソッドを呼び出すメソッドを持たせること。そうすることで、クラスに他のクラスの機能を組み込むことができる。
オブジェクト指向用語。
厳密なオブジェクト指向では、継承は「機能の継承」を目的とせず、「スーパークラスはサブクラスの一種である」といういわゆる「is-a」の関係を持たなければならない。
そのため、単に機能を持たせたい場合には、継承ではなく集約を使用することが推奨される。
メリットとして、「機能の継承」はクラスの関連図をイメージする際に分かりにくくなりやすいためそれを回避できる、メソッドをワンクッション置くことで融通が効く、といったものがある。また、集約の対象となるクラスは、そのサブクラスも使用できることになる。
デメリットとしては、同じメソッドを作らなければならない、集約の対象となるクラスに変更があった場合には同じように変更しなければならない場合がある、等である。
Java的には、言語仕様上特別なことは必要なく、単にフィールドとして別クラスを持ち、その別クラスを呼び出すメソッドを作ればよい。
つまり、集約とはシンタックスではなくセマンティクスな用語である。
似たようなものに「コンポジション」がある。
コンポジションと集約は非常に似ており、オブジェクト指向の常としてこの両者は曖昧である。
一応、コンポジションは集約の一種であり、集約の中でも元のクラスと対象のクラスの結び付きが強く寿命が同じであるという差異があるが、Javaでは実装上その差を付けることは難しい。
特定のクラスの機能を、自分が作るクラスにも持たせたい場合に、継承を使わずフィールドとしてそのクラスを持ち、そのクラスのメソッドを呼び出すメソッドを持たせること。そうすることで、クラスに他のクラスの機能を組み込むことができる。
オブジェクト指向用語。
厳密なオブジェクト指向では、継承は「機能の継承」を目的とせず、「スーパークラスはサブクラスの一種である」といういわゆる「is-a」の関係を持たなければならない。
そのため、単に機能を持たせたい場合には、継承ではなく集約を使用することが推奨される。
メリットとして、「機能の継承」はクラスの関連図をイメージする際に分かりにくくなりやすいためそれを回避できる、メソッドをワンクッション置くことで融通が効く、といったものがある。また、集約の対象となるクラスは、そのサブクラスも使用できることになる。
デメリットとしては、同じメソッドを作らなければならない、集約の対象となるクラスに変更があった場合には同じように変更しなければならない場合がある、等である。
Java的には、言語仕様上特別なことは必要なく、単にフィールドとして別クラスを持ち、その別クラスを呼び出すメソッドを作ればよい。
つまり、集約とはシンタックスではなくセマンティクスな用語である。
似たようなものに「コンポジション」がある。
コンポジションと集約は非常に似ており、オブジェクト指向の常としてこの両者は曖昧である。
一応、コンポジションは集約の一種であり、集約の中でも元のクラスと対象のクラスの結び付きが強く寿命が同じであるという差異があるが、Javaでは実装上その差を付けることは難しい。
参考サイト
- (参考サイトはありません)
// Sample.java
public class Sample
{
public static void main( String[] args )
{
// 集約クラスを使ってみます。
StringBufferComposition compo = new StringBufferComposition();
compo.append( "あいうえお\n" );
compo.append( "かきくけこ\n" );
compo.append( "さしすせそ\n" );
System.out.println( compo.toString() );
// あいうえお
// かきくけこ
// さしすせそ
}
}
/**
* StringBufferの集約クラス。
*/
class StringBufferComposition
{
/**
* 集約の対象クラス。
*/
private StringBuffer strbuf = new StringBuffer();
/**
* 文字列を追加します。
*/
public StringBufferComposition append( String string )
{
strbuf.append( string );
return this;
}
/**
* 文字列を取得します。
*/
public String toString()
{
return strbuf.toString();
}
}
public class Sample
{
public static void main( String[] args )
{
// 集約クラスを使ってみます。
StringBufferComposition compo = new StringBufferComposition();
compo.append( "あいうえお\n" );
compo.append( "かきくけこ\n" );
compo.append( "さしすせそ\n" );
System.out.println( compo.toString() );
// あいうえお
// かきくけこ
// さしすせそ
}
}
/**
* StringBufferの集約クラス。
*/
class StringBufferComposition
{
/**
* 集約の対象クラス。
*/
private StringBuffer strbuf = new StringBuffer();
/**
* 文字列を追加します。
*/
public StringBufferComposition append( String string )
{
strbuf.append( string );
return this;
}
/**
* 文字列を取得します。
*/
public String toString()
{
return strbuf.toString();
}
}
// Sample.java public class Sample { public static void main( String[] args ) { // 集約クラスを使ってみます。 StringBufferComposition compo = new StringBufferComposition(); compo.append( "あいうえお\n" ); compo.append( "かきくけこ\n" ); compo.append( "さしすせそ\n" ); System.out.println( compo.toString() ); // あいうえお // かきくけこ // さしすせそ } } /** * StringBufferの集約クラス。 */ class StringBufferComposition { /** * 集約の対象クラス。 */ private StringBuffer strbuf = new StringBuffer(); /** * 文字列を追加します。 */ public StringBufferComposition append( String string ) { strbuf.append( string ); return this; } /** * 文字列を取得します。 */ public String toString() { return strbuf.toString(); } }