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) で作られていくようにすると、継承よりも、より柔軟な構造を作ることができる。
宿題
今日は宿題はなしとします。