委譲とは? わかりやすく解説

い‐じょう〔ヰジヤウ〕【委譲】

読み方:いじょう

[名](スル)権利権限などを他の人・機関に譲って任せること。「執行権を—する」

「委譲」に似た言葉

委譲

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2019/07/11 16:22 UTC 版)

ナビゲーションに移動 検索に移動

委譲 (: delegation) とはオブジェクト指向プログラミングにおいて、あるオブジェクトの操作を一部他のオブジェクトに代替させる手法のこと。

概要

委譲を行うオブジェクトは委譲先オブジェクトへの参照を持ち、必要に応じてその参照を切り替える事で動作にバリエーションを持たせる事ができる。一種の実装遅延、プラグイン機構である。一例としては、オブジェクトの編集を行う時、編集の前処理、後処理を本処理と独立させ委譲先に任せる事で、オブジェクト本体の変更を最小限にとどめ局所性を向上させる、などがある。

操作の代替という観点では他に代理 (Proxy) と呼ばれる手法があるが、この場合は代理側のオブジェクトが実体への参照を保持する事で操作のフィルタを行う概念であり、実装の分離を目的とする委譲とは異なる。

委譲を引き受けるオブジェクトはどのような操作を実装しなければならないか知っている必要があるため、インタフェースと併用される場合が多い。

いくつかの言語ではデザインパターンにおける手法であり、いくつかの言語ではコードで実装されライブラリとして提供されている。

C++

#include <iostream>

struct ExampleInterface {
    virtual void Print() = 0;
};

class Something1 : public ExampleInterface {
public:
    void Print() {
        std::cout << "Something1::Print() is called." << std::endl;
    }
};

class Something2 : public ExampleInterface {
public:
    void Print() {
        std::cout << "Something2::Print() is called." << std::endl;
    }
};

class SomethingDelegator {
    ExampleInterface *implementer;
public:
    SomethingDelegator() : implementer() {
    }

    void setImplementer(ExampleInterface *something) {
        implementer = something;
    }

    void ExecuteProcess() {
        // 処理の詳細をExampleInterface::Print関数の実装者に委譲している
        if (implementer) {
            implementer->Print();
        }
    }
};

int main() {
    SomethingDelegator delegator;

    Something1 source1;
    delegator.setImplementer(&source1);
    // Something1::Print関数が呼ばれる
    delegator.ExecuteProcess();

    Something2 source2;
    delegator.setImplementer(&source2);
    // Something2::Print関数が呼ばれる
    delegator.ExecuteProcess();

    return 0;
}

Java

class A {
    public void foo() {
        System.out.println("A.foo() is called.");
    }
}

class B {
    private A a = new A();
    public void bar() {
        a.foo();
    }
}

JavaScript

SelfJavaScriptといったプロトタイプベースの言語では、言語機能として委譲と継承の中間とも言えるプロトタイプ機能を備えており、委譲先のオブジェクトを書き換えることはできないものの手軽に委譲ができるようになっている。

プロトタイプを使った委譲の例:

/*
共通の反復処理を提供するオブジェクトとしてIterableを定義。

// Iterableはprototype(委譲先)の要件としてdoEachを要求する。
this.doEach = function( aBlock )
{
	// subclassResponsibility;
}
*/
Iterable = function()
{
	this.copyEmpty = function()
	{
		return [];
	}
	
	// 委譲先に追加する要素の選択関数
	this.select = function( aBlock )
	{
		var result = this.copyEmpty();

		this.doEach
		(
			function( anEach )
			{
				if( aBlock( anEach ) ) result.push( anEach );
			}
		);

		return result;
	}
}

BaseCollection = [ 0, 1, 2, 3, 4 ];
BaseCollection.doEach = function( aBlock )
{
	for( var i = 0; i < this.length && false !== aBlock( this[ i ] ); ++i ) ;
}
// 配列にselect( aBlock )を追加する。
Iterable.prototype = BaseCollection;
Collection = new Iterable().select( function( aEach ){ return 3 < aEach } );

BaseCollection = { 0: 4, 1: 3, 2: 2, 3: 1, 4: 0 };
BaseCollection.doEach = function( aBlock )
{
	for( var i in this )
	{
		if( false === aBlock( this[ i ] ) ) return;
	}
}
// 連想配列にselect( aBlock )を追加する。
Iterable.prototype = BaseCollection;
Collection = new Iterable().select( function( aEach ){ return 3 < aEach } );

なお、Selfの様に純粋なプロトタイプベースの言語ではprototype変数やnewに相当するものは無い。単純にプロトタイプとなるオブジェクトを委譲先としてオブジェクトを生成する機能のみ備わっているため、JavaScriptの様に委譲元を再利用するにはメソッド等サブルーチンの追加が必要となる。

Objective-C

Objective-Cの例を説明する。Objective-Cではデリゲート先のオブジェクトはどんなオブジェクトでも構わない。デリゲートしないときはnilを指定してもよい。Objective-CC++Javaとは異なり実行時解決を採用しているので、デリゲート先に指定したオブジェクトが必要なメソッドを持っていなくてもコンパイルエラーにはならず、単に何も実行されないだけである。文法上で特殊な扱いはされておらず、平時の記述の枠内で処理される典型的な実装パターンとして用いられる。

あるオブジェクトAがメインウィンドウを持っていて、そのAにメインウィンドウの処理を委譲する場合

[mainWindow setDelegate: self];

selfは自分自身を指すポインタである。[ ]内はC言語に対してObjective-Cで拡張された文法で、インスタンス変数mainWindowに対してsetDelegateメッセージを送っている。

このdelegateを設定することで、Aがメインウィンドウの処理、たとえばウィンドウを閉じる前に何かしたい場合に用いるメソッドwindowWillCloseをかわりに実行するようになる。Aに

-(void)windowWillClose:(NSNotification*)notification
{
    // 処理
}

のようなメソッドを用意しておけば、ウィンドウのクラス(NSWindow)に修正を加えたり、NSWindowを継承したクラスを作らなくても振る舞いをカスタマイズすることができる。

Smalltalk

Smalltalkにおける委譲も基本的には他の言語と同じである。 ただし、メッセージ機構を利用することでSmalltalk独特の委譲を行うことが出来る。 Smalltalkは、オブジェクトに対しメッセージが送られた際、メッセージ内のセレクターに該当するメソッドがオブジェクト内に無ければ、そのメッセージはdoesNotUnderstand:メソッドに送られる。この時doesNotUnderstand:メソッドで受け取ったメッセージは自由に他のオブジェクトに送りつけることが出来る。

なお、Objective-CにもdoesNotUnderstand:と同等の仕組みが存在し、同様の処理を記述できる。上記のObjective-Cの委譲もこのメッセージ処理の仕組みを利用している。

委譲用クラスの定義例:

"他のオブジェクトに委譲するクラスの登録"
Object
        subclass:               #MouseDelegator     "ObjectクラスからDelegatorクラスを派生させる。"
        instanceVariableNames:  'deletage filter'   "委譲先のフィールド( メンバー変数 )を定義"
        classVariableNames:     ''
        poolDictionaries:       ''
        category:               'ExampleDelegate'.
        
MouseDelegator methodsFor: 'accessing for delegate'
!
deletage
	^deletage
!
deletage: anObject
	deletage := anObject.
!!

MouseDelegator methodsFor: 'accessing for filter'
!
filter
	^ filter.
!
filter: anObject
	filter := anObject.
!!

MouseDelegator methodsFor: 'event handling'
!
click
	"clickメッセージをaTargetに委譲する"
	self filter click.
!!

MouseDelegator methodsFor: 'message fowarding'
!
doesNotUnderstand: aMessage 
	"click以外のメッセージは全てdelegateに委譲する。"
	aMessage sendTo: self delegate.
!!

MouseDelegator class methodsFor: 'instance creation'
!
withDelegate:   aDelegateObject
withFilter:     aFilterObject

	"MouseDelegatorのインスタンスオブジェクトを生成し、初期化する。"
	^ ( self new ) deletage: aDelegateObject; filter: aFilterObject.
!!

委譲用クラスの使用例:

| delegator |

delegator := MouseDelegator withDelegate: ( OtherExample new ) withFilter: ( Example new ).
delegator click.       "Exampleのインスタンスオブジェクトにclickメッセージが送られる。"
delegator doubleClick. "OtherExampleのインスタンスオブジェクトにdoubleClickメッセージが送られる。"

参考

Go

Go言語においては、他の言語と異なり始めから委譲を想定した委譲専用構文を備えている。 Go言語では、表向き継承機能を持っていないが、この委譲構文によって継承に必要とされる殆どの機能を実現できる。例えば多重継承も可能であるが、基底型から派生型のメンバーを呼び出すようなことは出来ない。

下記にGoの委譲機能を使って、線分の頂点座標しか表示できない型に対して、Bezier曲線の頂点座標表示能力を付与する例を示す。

type Point2D struct {
        X, Y float64
}
 
func AxisX( point Point2D ) float64 {
        return point.X
}
 
func AxisY( point Point2D ) float64 {
        return point.Y
}
 
/* 線分描画機能を定義した型 */
type SimpleContext interface {
        Location() Point2D
        MoveTo( point Point2D )
        LineTo( point Point2D )
}
 
/* 線分描画及びBezier曲線描画機能を定義した型 */
type BezierContext interface {
        Location() Point2D
        MoveTo( point Point2D )
        LineTo( point Point2D )
        CubicBezierTo( control1, control2, point Point2D )
}
 
/* SimpleContext型にBezier曲線描画機能を付与する型 */
type BezierAdapterContext struct {
	/*
	委譲先の型名を記述する事でBezierAdapterContextに対し呼び出された
	Location、MoveTo、LineToは、記述した型に自動で委譲される。
	*/
        SimpleContext
}
 
func ( this *BezierAdapterContext ) CubicBezierTo( control1, control2, end Point2D ) {
        start := this.Location()
 
        cubicBezier := func( axis func( Point2D ) float64, t float64 ) float64 {
                dis_t := 1.0 - t
 
                return  axis( start ) * math.Pow( dis_t, 3 ) +
                        axis( end ) * math.Pow( t, 3 ) +
                        3 * t * dis_t *
                        ( axis( control1 ) * dis_t *  + axis( control2 ) * t )
        }
 
        split := 10
        for i := 0; i < split; i++ {
                t := float64( i ) / float64( split )
 
                this.LineTo( Point2D {
                        X:cubicBezier( AxisX, t ),
                        Y:cubicBezier( AxisY, t ),
                } )
        }
}

/* 線分の現在地管理し、入力された線分座標を表示する型 */
type BasicContext struct {
        current Point2D
}
 
func ( this *BasicContext ) Location() Point2D {
        return this.current
}
 
func ( this *BasicContext ) MoveTo( point Point2D ) {
        this.current = point
}
 
func ( this *BasicContext ) LineTo( point Point2D ) {
        this.MoveTo( point )
        fmt.Printf( "%f @ %f\n", point.X, point.Y )
}
 
func main() {
	/*
	BezierAdapterContext型からBasicContext型への委譲関係構築。
	BasicContextに対し、Bezier曲線の座標を表示する能力が付与される。
	*/
        base_context := BasicContext{}
        var context BezierContext = &BezierAdapterContext{ SimpleContext: &base_context }

	/* BasicContext型に委譲される */
        context.MoveTo( Point2D{ X:0, Y:0 } )
        context.LineTo( Point2D{ X:20, Y:20 } )

	/* BezierAdapterContext型が直接処理する */
        context.CubicBezierTo( Point2D{ X:50, Y:-100 }, Point2D{ X:100, Y:100 }, Point2D{ X:200, Y:0 } )
}

Ruby

crubyでは標準添付のdelegateライブラリを利用して委譲が使える。

関連項目


委譲

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2021/11/26 04:32 UTC 版)

コンポーネント図」の記事における「委譲」の解説

委譲は、親コンポーネントと子コンポーネントとの関係を表現できる。 親コンポーネントのどのインタフェースが子コンポーネントのどのインタフェース委譲しているのか、また親コンポーネントのどの必須インタフェースが子コンポーネントのどの必須インタフェースとなっているのかを記述できる。 それぞれ、親コンポーネントインタフェースから子コンポーネントインタフェースへの矢印、子コンポーネント必須インタフェースから親コンポーネント必須インタフェースへの矢印表現する

※この「委譲」の解説は、「コンポーネント図」の解説の一部です。
「委譲」を含む「コンポーネント図」の記事については、「コンポーネント図」の概要を参照ください。

ウィキペディア小見出し辞書の「委譲」の項目はプログラムで機械的に意味や本文を生成しているため、不適切な項目が含まれていることもあります。ご了承くださいませ。 お問い合わせ

委譲

出典:『Wiktionary』 (2021/08/21 10:03 UTC 版)

名詞

いじょう

  1. 譲り任せること。

動詞

活用

サ行変格活用
委譲-する

「委譲」の例文・使い方・用例・文例

Weblio日本語例文用例辞書はプログラムで機械的に例文を生成しているため、不適切な項目が含まれていることもあります。ご了承くださいませ。



品詞の分類


英和和英テキスト翻訳>> Weblio翻訳
英語⇒日本語日本語⇒英語
  

辞書ショートカット

すべての辞書の索引

「委譲」の関連用語

委譲のお隣キーワード
検索ランキング

   

英語⇒日本語
日本語⇒英語
   



委譲のページの著作権
Weblio 辞書 情報提供元は 参加元一覧 にて確認できます。

   
デジタル大辞泉デジタル大辞泉
(C)Shogakukan Inc.
株式会社 小学館
ウィキペディアウィキペディア
All text is available under the terms of the GNU Free Documentation License.
この記事は、ウィキペディアの委譲 (改訂履歴)の記事を複製、再配布したものにあたり、GNU Free Documentation Licenseというライセンスの下で提供されています。 Weblio辞書に掲載されているウィキペディアの記事も、全てGNU Free Documentation Licenseの元に提供されております。
ウィキペディアウィキペディア
Text is available under GNU Free Documentation License (GFDL).
Weblio辞書に掲載されている「ウィキペディア小見出し辞書」の記事は、Wikipediaのコンポーネント図 (改訂履歴)の記事を複製、再配布したものにあたり、GNU Free Documentation Licenseというライセンスの下で提供されています。
Text is available under Creative Commons Attribution-ShareAlike (CC-BY-SA) and/or GNU Free Documentation License (GFDL).
Weblioに掲載されている「Wiktionary日本語版(日本語カテゴリ)」の記事は、Wiktionaryの委譲 (改訂履歴)の記事を複製、再配布したものにあたり、Creative Commons Attribution-ShareAlike (CC-BY-SA)もしくはGNU Free Documentation Licenseというライセンスの下で提供されています。
Tanaka Corpusのコンテンツは、特に明示されている場合を除いて、次のライセンスに従います:
 Creative Commons Attribution (CC-BY) 2.0 France.
この対訳データはCreative Commons Attribution 3.0 Unportedでライセンスされています。
浜島書店 Catch a Wave
Copyright © 1995-2025 Hamajima Shoten, Publishers. All rights reserved.
株式会社ベネッセコーポレーション株式会社ベネッセコーポレーション
Copyright © Benesse Holdings, Inc. All rights reserved.
研究社研究社
Copyright (c) 1995-2025 Kenkyusha Co., Ltd. All rights reserved.
日本語WordNet日本語WordNet
日本語ワードネット1.1版 (C) 情報通信研究機構, 2009-2010 License All rights reserved.
WordNet 3.0 Copyright 2006 by Princeton University. All rights reserved. License
日外アソシエーツ株式会社日外アソシエーツ株式会社
Copyright (C) 1994- Nichigai Associates, Inc., All rights reserved.
「斎藤和英大辞典」斎藤秀三郎著、日外アソシエーツ辞書編集部編
EDRDGEDRDG
This page uses the JMdict dictionary files. These files are the property of the Electronic Dictionary Research and Development Group, and are used in conformance with the Group's licence.

©2025 GRAS Group, Inc.RSS