の続きです、まだお読みで無い方はぜひ読んでみて下さい(ダイレクトマーケティング)
前回はAdapterパターンを継承で書いてみましたが、委譲による実装方法もあるので作ってみたいと思います。
継承との主な違い
継承では既存のクラス、今回で言うBannerクラスを継承することで実現していました。
委譲では既存のクラスのインスタンスを作って作業をぶん投げる(委譲)ことで実現しています。
委譲はちょっと馴染みの無い言葉ですが要は作業をぶん投げることです(誤解があったらごめんなさい)
ざっくりまとめると
- 継承を使ったパターン
- 既存のクラスを継承して、親クラスとなった既存のクラスのメソッドを使うことで実現
- 委譲を使ったパターン
- 既存のクラスのインスタンスを生成して、作ったインスタンスのメソッドを使うことで実現
となります。
サンプル
Bannerクラス
継承のときと変わっていません。
export class Banner { private string_: string; constructor(string: string) { this.string_ = string; } public showWithParen(): void { console.log("(" + this.string_ + ")"); } public showWithAster(): void { console.log("*" + this.string_ + "*"); } }
Main(実行ファイル)
継承のときと変わっていません。
以前と同様Bannerクラスの中身は全く知らずに使っています。
import { PrintBanner } from './printBanner' import { Print } from './print' const p: Print = new PrintBanner("Hello"); p.printWeak(); p.printStrong();
Printクラス
インターフェースから抽象クラスになりました。
次のPrintBannerクラスではこのPrintクラスを継承し、振る舞いを実装します。
前回の場合Bannerクラスを継承していたためPrintクラスを継承できなかった(多重継承になる)のですが、今回はBannerクラスを継承していないため、Printクラスを抽象クラスにして継承をしています。(「継承」が多すぎて訳がわからん)
export abstract class Print { abstract printWeak(): void; abstract printStrong(): void; }
PrintBannerクラス
心臓部のこのクラスが一番変わります、中で既存のそのまま使いたくないBannerクラスのインスタンスを生成して使うことで、printWeak()
メソッド等を実装しています。
import { Banner } from "./banner" import { Print } from "./print" export class PrintBanner extends Print { private banner: Banner; constructor(string: string) { super(); // Bannerクラスのインスタンスを生成 this.banner = new Banner(string); } public printWeak(): void { // Bannerインスタンスを使って実装 this.banner.showWithParen(); } public printStrong(): void { // Bannerインスタンスを使って実装 this.banner.showWithAster(); } }
実行結果
$ node main.js (Hello) *Hello*
継承のときと変わりません。
まとめ
どっちが良いとかはあまり言及されていなかったので、好きな方を使えば良いのかなと思います。
個人的にはtypescriptは多重継承が使えないのと、継承は慎重に使っていきたいという考えがあるので、委譲の方が使いやすそうに思っています。また長所短所が把握できたらまとめていきたいと思います。
では今回はここまでです。ありがとうございました。