私のバックグラウンドを簡潔に話すとC++,Haskell,Python,TypeScript,Nimでの開発経験があります。その前提で、現時点でやらない方がいいデザインパターンについて共有したいと思います。
現代のツールや言語仕様では冗長で非効率的なデザインパターンについて説明します。
以下はECMAScript前提の話なので、話半分に聞いて下さい。
まずFactoryパターン。これはもう完全にいらないです。読むのに邪魔なので。
デコレータパターンも不要です。
というか人類は普通に素直にオブジェクトの特性を生かすことを考えた方がいいです。
オブジェクトの基礎を勉強すべきです。
オブジェクトとは、「データ(プロパティ)とそれに関する操作(メソッド)をまとめた構造」のことで、
const user = {
name: "Alice",
age: 25,
greet() {
return `Hello, my name is ${this.name}`;
},
};
みたいなやつのことです。
この言語においてはオブジェクトが非常に強いので、オブジェクトを利用することでデータ構造を扱うのが異常に楽です。他の言語をやったことのあるひとなら頷いてくれると思います。
以下辛辣にバサバサ
1. Factoryパターン
- オブジェクト生成を直接記述する方がシンプルである
2. デコレータパターン
- 関数型プログラミングのアプローチでいい
- 関数合成とかで同等の記述ができるが、そもそもそういう面倒なことになったらコードがおかしい
3. シングルトンパターン
- そもそもシングルトンパターンが出来た経緯を考えるとDIコンテナで良くないかとなる
4. プロキシパターン
- ES6の
Proxy
オブジェクトでよい
で、実際学ぶべきなのはオブジェクトそのものの扱いです。
あと関数型プログラミングの知恵。
高階関数の取り扱いとかをやるといいと思います。
たとえばFactoryパターン、
class User {
constructor(public name: string, public age: number) {}
}
class UserFactory {
static createUser(name: string, age: number): User {
return new User(name, age);
}
}
const user = UserFactory.createUser("Alice", 25);
これを、こうじゃい
class User {
constructor(public name: string, public age: number) {}
}
const createUser = (name: string, age: number) => new User(name, age);
const user = createUser("Alice", 25);
普通にひらたくcreateUserを書けばいい(この場合はコンストラクタそのままでもいいが)
アダプタパターンだと
class OldSystem {
oldMethod() {
return "Old System";
}
}
class Adapter {
constructor(private oldSystem: OldSystem) {}
newMethod() {
return this.oldSystem.oldMethod();
}
}
const oldSystem = new OldSystem();
const adapter = new Adapter(oldSystem);
console.log(adapter.newMethod());
class OldSystem {
oldMethod() {
return "Old System";
}
}
const adaptOldSystem = (oldSystem: OldSystem) => () => oldSystem.oldMethod();
const oldSystem = new OldSystem();
const newMethod = adaptOldSystem(oldSystem);
console.log(newMethod());
で等価ですが、そもそもこの種のデザインパターンが必要になった段階でコード自体が腐っているケースがほとんどです。
デザインパターンって全部銀の弾丸でしかなく、「銀の弾丸はない」。