- Perl ›
- オブジェクト指向プログラミング ›
- here
環境に応じたオブジェクトを作成する
クラスを少しだけ改造してOSに応じて振る舞いを変更するようにしてみましょう。
(このコンテンツは今後更新されまぜん。内容が古かったり、不適切な内容を含む可能性があります。)
1. 環境に応じて振る舞いを変えるポリモーフィズム
環境がWindowsだった場合は、FilePath::Windowsクラスのオブジェクトを作成して、環境がそれ以外だったら、FilaPath::Unixクラスのオブジェクトを作成するクラスを書いてみました。
use strict; use warnings; my $file_path = FilePath->new; my $result = $file_path->cat_path('a', 'b'); print "結果: $result\n"; # ユーザが利用するクラス package FilePath; sub new { my $self = shift; if ($^O eq 'MSWin32') { return FilePath::Windows->new; } else { return FilePath::Unix->new; } } # ファイルパスを扱うための基底クラス package FilePath::Base; sub new { my $proto = shift; my $class = ref $proto || $proto; my $self = {}; bless $self, $class; return $self; } sub cat_path { my ($self, $str1, $str2) = @_; return $str1 . $self->delimiter . $str2; } # Unix 用 package FilePath::Unix; use base 'FilePath::Base'; # Unixの場合の区切り文字 sub delimiter{ return '/' } # Windows用 package FilePath::Windows; use base 'FilePath::Base'; # Windowsの場合の区切り文字 sub delimiter{ return '\\' }
実行結果は、環境がWindowsの場合は、
結果: a\b
それ以外の場合は、
結果: a/b
となります。環境がWindowsの場合は、FilePath::Windowsクラスのオブジェクトが生成されて、それ以外の場合は、FilePath::Unixクラスのオブジェクトが生成されているということです。
print ref $file_path;
とするとどのクラスのオブジェクトが作成されているかが見えると思います。
2. コンストラクタで振る舞いを変える
ユーザが利用するクラスとして、FilePathというクラスを準備しました。このクラスのコンストラクタが、環境に応じたオブジェクトを生成してくれます。(一般的には、ファクトリークラスと呼ばれるものになります。)
package FilePath; sub new { my $self = shift; if ($^O eq 'MSWin32') { return FilePath::Windows->new; } else { return FilePath::Unix->new; } }
$^O を見てOSの種類を調べて、作成するオブジェクトを変更しています。この例のコンストラクタは引数を受け取りませんが、コンストラクタというのは、一般的には引数を受け取るので
sub new { my $self = shift; if ($^O eq 'MSWin32') { return FilePath::Windows->new(@_); } else { return FilePath::Unix->new(@_); } }
と記述する場合のほうが多いです。3項演算子を使って書くとさらにすっきりします。
sub new { my $self = shift; return $^O eq 'MSWin32' ? FilePath::Windows->new(@_) : FilePath::Unix->new(@_); }
3. 継承の便利なところ
継承をうまく使えば、環境に応じた振る舞いをさせる記述をすっきと記述することができることがわかると思います。
また、ほかの環境にも対応させたい場合は「FilePath::ほにゃらら」というクラスを作って、FilePathクラスのコンストラクタを少し修正すれば良いだけです。
つまりどのような場面で継承が威力を発揮するかといえば、数多くのパターンが存在して、拡張の可能性が高い場面ということになります。
4. 継承が難しいと感じる場合は
このサンプルをデバッガでたどってください。クラスの間をどういう風に動き回っているかを、観察すれば、理解できてくるはずです。
$^O の値を変えれば、Windows の場合や、Unixの場合をエミュレートできます。また、ref関数を使って、作成されたオブジェクトが属するクラスを見たりしてください。