Software Engineering Lecture 6/27

Menu Menu


先週の復習


CardPlay のオブジェクト


CardPile

split/merge の取扱


Card


Board

Drag/Undo などの機能を持つ


ドラッグ

    $c->bind('point', '<1>' => [sub {plot_down(@ARG)}, \%pinfo]);
    $c->bind('point', '<ButtonRelease-1>' => sub {shift->dtag('selected')});
    $c->Tk::bind('<B1-Motion>' => [sub {plot_move(@ARG)}, \%pinfo]);
    sub plot_down {
	my($w, $pinfo) = @ARG;
	my $e = $w->XEvent;
	my($x, $y) = ($e->x, $e->y);
	$w->dtag('selected');
	$w->addtag('selected', 'withtag', 'current');
	$w->raise('current');
	$pinfo->{'lastX'} = $x;
	$pinfo->{'lastY'} = $y;
    } # end plot_down
    sub plot_move {
	my($w, $pinfo) = @ARG;
	my $e = $w->XEvent;
	my($x, $y) = ($e->x, $e->y);
	$w->move('selected',  $x-$pinfo->{'lastX'}, $y-$pinfo->{'lastY'});
	$pinfo->{'lastX'} = $x;
	$pinfo->{'lastY'} = $y;
    } # end plot_move


ドラッグ&ドロップ

問題

以下の仕組みを協調図を使って表示して見よ。


Undo

Command Pattern を使った Undo の仕組みを理解しよう。

    sub log_move {
	my ($self) = shift;
	my ($undo) = @_;
	return if ($self->{'-undoing'}==1);
	return if ($undo==0);
	$self->{'-undo'}->[$self->{'-undo_index'}]=$undo;
	$#{$self->{'-undo'}} = $self->{'-undo_index'}++;
    #    print STDERR "log_move: "; $undo->print();
    }
    sub undo {
	my ($self) = shift;
	my ($undo);
	return if ($self->{'-undo_index'}==0);
	return if ($self->{'-undoing'}++>0);
	return if ($self->{'-undoing'}!=1);
	$self->disable_undo;
	while ( $self->{'-undo_index'} > 0 ) {
	    $undo = $self->{'-undo'}->[$self->{'-undo_index'}-1];
	    last if ($undo==-1);
	    last if ($undo!=0);
	    $self->{'-undo_index'} --;
	}
	while ( $self->{'-undo_index'} > 0 ) {
	    $undo = $self->{'-undo'}->[$self->{'-undo_index'}-1];
	    last if ($undo== -1);
	    $self->{'-undo_index'} --;
	    last if ($undo==0);
	    $undo->undo();
	}
	$self->{'-undoing'}=0;
	$self->enable_undo;
    }


委譲と継承

継承は、オブジェクト指向言語の機能として実現されていてるが、委譲は、それとは関係なく自分で実装することができる。Perl でも、

    package class1;
    sub method1 {
	my $self = shift;
	$self->{-delegate1}->method1(@_);
    }

みたいな形で委譲を実現することができる。これは、class1 のオブジェクトと、$self->{-deletage1} のオブジェクトの協調動作ということになる。

委譲を使うと、継承と異なり、委譲先を実行時に変更することができる。また、必要ならば、委譲先を、lazy に生成することもできる。また、メソッドの選択を継承のように言語の機能に頼ることなく、自分で行うことができるのも利点である。

ただし、メッセージの転送が必要になるので、実行のオーバヘッドは若干生じる。これは、適応性や再利用性をとるか、実行時の効率をとるかという問題になる。

オブジェクトは、このようなオブジェクトの組み合わせ(Object Composition) で作られていくようにすると、継承よりも、より柔軟な構造を作ることができる。


宿題

今日は宿題はなしとします。


Shinji KONO / Tue Jul 4 14:49:02 2000