小池啓仁 ヒロヒト応援ブログ By はてな

小池啓仁(コイケヒロヒト)の動画など。

小池啓仁 ヒロヒト応援ブログ By はてな

Perlでアダプターパターン! (デザインパターン)

アダプターサンプルのクラス図

       Client
     +-------------+
     | Main        |
     +-------------+
     |             |
     +-------------+
     |             |
     +-------------+
            |
            |
            | 使用:関連
            v
     +-------------+            +-------------+            +------------------+
     | Target      |            | Adapter     |            | Adaptee          |
     +-------------+            +-------------+            +------------------+
     |             |#-----------| adaptee     |o---------->|                  |
     +-------------+ 継承:汎化 +-------------+ 委譲:集約 +------------------+
     | request()   |            | request()   |            | specialRequest() |
     +-------------+            +-------------+            +------------------+


では、以下で、アダプターパターンでのJavaソースとそれをPerlでリメイクしたソースとの違いをご確認ください。
尚、Javaのソースは「オブジェクト指向 WITH JAVA:アダプターパターン」のと同じです。

アダプターサンプルのソース

ターゲットクラス(やりたいことを抽象レベルで考えたクラスです)

Target.java

public abstract class Target {
    public abstract void printEm();
    public abstract void printStrong();
}

Target.pm

package Target;
use strict;
    sub printEm{die "オーバーライド必須";}
    sub printStrong{die "オーバーライド必須";}
1;
アダプティ−クラス(やりたいことが似ている具象クラスです)

Adaptee.java

public class Adaptee {
    private String string;
    public Adaptee(String string) {
        this.string = string;
    }
    public void showWithParen() {
        System.out.println("(" + string + ")");
    }
    public void showWithAster() {
        System.out.println("*" + string + "*");
    }
    public void showWithSemicolon() {
        System.out.println(";" + string + ";");
    }
    public void showWithPercent() {
        System.out.println("%" + string + "%");
    }
}

Adaptee.pm

package Adaptee;
use strict;
    sub  new {
        my $class = shift;
        my $string = shift;
        return bless {string => $string}, $class;
    }
    sub showWithParen {
        my $self = shift;
        print "\($self->{string}\)", "\n";
    }
    sub showWithAster {
        my $self = shift;
        print "\*$self->{string}\*", "\n";
    }
    sub showWithSemicolon {
        my $self = shift;
        print "\;$self->{string}\;", "\n";
    }
    sub showWithPercent {
        my $self = shift;
        print "\%$self->{string}\%", "\n";
    }
1;
アダプタークラス(ターゲットクラスとアダプティ−クラスを繋ぐ(適合)クラスです。ターゲットクラスを継承し、アダプティ−クラスを委譲します)

Adapter.java

public class Adapter extends Target {
    private Adaptee adaptee;
    public Adapter(String string) {
        this.adaptee = new Adaptee(string);
    }
    public void printEm() {
        adaptee.showWithParen();
    }
    public void printStrong() {
        adaptee.showWithAster();
    }
}

Adapter.pm

package Adapter;
use strict;
use base 'Target';
use Adaptee;
    sub  new {
        my $class = shift;
        my $string = shift;
        my $adaptee = Adaptee->new($string);
        return bless {adaptee => $adaptee}, $class;
    }
    sub printEm {
        my $self = shift;
        $self->{adaptee}->showWithParen;
    }
    sub printStrong {
        my $self = shift;
        $self->{adaptee}->showWithAster;
    }
1;
メインクラス

Main.java

public class Main {  //client
    public static void main(String[] args) {
        Target p = new Adapter("Hello");
        p.printEm();
        p.printStrong();
    }
}

Main.pl

use strict;
use Adapter;
        my $p = Adapter->new("Hello");
        $p->printEm();
        $p->printStrong();