私が初めてソフトウェア開発の世界に飛び込み始めたとき、飛び交うあらゆる流行語や概念に圧倒されることがよくありました。特に困難に思えた概念の 1 つは、SOLID 原則でした。それは「真剣な」開発者だけが心配する必要があることのように感じました。しかし、コーディングに慣れてくると、これらの原則は派手なことではなく、数カ月後に髪の毛を抜きたくなくなるようなコードを書くことであることがわかりました。
それでは、JavaScript の SOLID 原則についての私の見解をご紹介します。これは、JavaScript を始めるときにあればよかったと思っている、実用的で実用的なガイドです。
単一責任原則では、クラスが変更する理由は 1 つだけであるべきであり、つまり、クラスの仕事または責任は 1 つだけであるべきであると述べられています。
お気に入りのコーヒーショップのバリスタを思い浮かべてください。彼らの仕事はコーヒーを作ることです。突然、エスプレッソマシンを修理したり、ペストリーを提供したり、ゴミを出したりしなければならなくなったら、事態は混乱するでしょう。バリスタがコーヒーを作ることに集中するのと同じように、クラスでも 1 つのことをうまくやることに集中する必要があります。
ユーザー認証、データ検証、データベース ストレージを処理する User クラスがあると想像してください。やりすぎだよ!これらの責任を個別のクラスに分割することで、コードの管理と保守が容易になります。
class UserAuthenticator { login(user) { // handle login } } class UserDataValidator { validate(user) { // validate user data } } class UserDatabase { save(user) { // save user to the database } }
オープン/クローズド原則では、ソフトウェア エンティティは拡張に対してオープンであるが、変更に対してはクローズされるべきであると規定されています。言い換えれば、既存のコードを変更せずに新しい機能を追加できる必要があります。
お気に入りのゲーム機を想像してみてください。新しいゲーム、コントローラー、アクセサリを追加できますが、そのために開いて再配線する必要はありません。同様に、コードのコア構造を変更することなく、コードに新しい機能を追加できる必要があります。
面積を計算するメソッドを備えた Shape クラスがあるとします。三角形などの新しい形状を追加する必要がある場合、既存のクラスを変更する必要はありません。代わりに、それを拡張してください。
class Shape { area() { throw "Area method not implemented"; } } class Rectangle extends Shape { constructor(width, height) { super(); this.width = width; this.height = height; } area() { return this.width * this.height; } } class Circle extends Shape { constructor(radius) { super(); this.radius = radius; } area() { return Math.PI * this.radius * this.radius; } }
リスコフ置換原則では、プログラムの正確さに影響を与えることなく、スーパークラスのオブジェクトをサブクラスのオブジェクトに置き換えることができる必要があると述べています。
レンタカーを借りることを想像してみてください。セダンでも SUV でも、運転し、操縦し、停止するという車の基本的な機能を備えていることを期待します。レンタカーにまったく異なる制御セットが必要な場合は、大変なことになるでしょう。同様に、サブクラスは、親クラスによって設定された期待を裏切らない方法で動作する必要があります。
Bird クラスとそれを拡張した Penguin クラスがある場合、ペンギンは飛べなくても Bird のように動作するはずです。まだ歩き、食事をし、おそらく泳ぐこともできるはずです。
class Bird { move() { console.log("Flies in the sky"); } } class Penguin extends Bird { move() { console.log("Swims in the water"); } } const myBird = new Bird(); const myPenguin = new Penguin(); myBird.move(); // Flies in the sky myPenguin.move(); // Swims in the water
インターフェイス分離原則は、クライアントが使用しないインターフェイスの実装を強制すべきではないことを示唆しています。 1 つの大きなインターフェイスを用意する代わりに、より小さく、より具体的なインターフェイスを作成する必要があります。
シェフがウェイター、バーテンダー、食器洗い機を兼任するレストランを想像してみてください。それは圧倒的で非効率的です!代わりに、各役割に固有のタスクを持たせる必要があります。同様に、インターフェースも特化され、焦点が絞られたものである必要があります。
buildHouse、paintHouse、designHouse などのメソッドを含む Worker インターフェイスがある場合、家をペイントするだけの Worker は他のすべてのメソッドを実装する必要はありません。それをより小さなインターフェースに分割します。
class Builder { build() { console.log("Building house..."); } } class Painter { paint() { console.log("Painting house..."); } } class Designer { design() { console.log("Designing house..."); } }
依存関係逆転の原則では、高レベルのモジュールが低レベルのモジュールに依存すべきではないと述べています。どちらも抽象化に依存する必要があります。
携帯電話の充電器を壁のコンセントに差し込む方法を考えてみましょう。壁内の電気配線の詳細を知る必要はありません。必要なのは、デバイスに電力を供給するためのインターフェイス (ソケット) だけです。同様に、コードは具体的な実装ではなく、抽象化 (インターフェイス) に依存する必要があります。
Switch クラスを直接制御する LightBulb クラスがある場合、密結合が作成されます。代わりに、両方とも PowerSource.
のようなインターフェイスに依存する必要があります。
class LightBulb { turnOn(powerSource) { powerSource.provideElectricity(); console.log("Light is on"); } } class Switch { constructor(powerSource) { this.powerSource = powerSource; } operate() { this.powerSource.togglePower(); } } class PowerSource { provideElectricity() { console.log("Providing electricity"); } togglePower() { console.log("Toggling power"); } }
SOLID 原則をマスターすることは、一連の実証済みのレシピを使って料理を学ぶことに似ています。これらを理解すると、機能的であるだけでなく、エレガントで保守が容易なコードを作成できます。したがって、次回コーディングの難題に直面したときは、これには原則があることを思い出してください。
コーディングを楽しんでください! ?
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3