ホームページ ウェブフロントエンド jsチュートリアル JavaScriptを深く理解するシリーズ(6):単一責任S.O.L.I.Dの5原則のSRP_javascriptスキル

JavaScriptを深く理解するシリーズ(6):単一責任S.O.L.I.Dの5原則のSRP_javascriptスキル

May 16, 2016 pm 05:57 PM

前書き
ボブおじさんは、オブジェクト指向プログラミングをより適切に実装するために S.O.L.I.D の 5 つの原則を提案し、継承しました。 5 つの原則は次のとおりです。

単一責任原則 (単一責任 SRP)
オープン/クローズド。原則 (OCP)
リスコフ置換原則 (LSP)
インターフェース分離原則 (ISP)
依存性反転原則 (DIP)
5 つの原則はブログ コミュニティで議論されてきたと思います。特に C# の実装については、プロトタイプベースの動的型言語である JavaScript と比べるとまだ少ないため、このシリーズでは JavaScript プログラミング言語に基づいた 5 つの原則の適用について説明します。 OK、最初の記事「単一責任」を始めましょう。

英語原文: http://freshbrewedcode.com/derekgreer/2011/12/08/solid-javascript-single-responsibility-principle/

単一責任
単一の説明責任は次のとおりです:

クラスを変更する理由は 1 つだけである必要があります
クラスを変更する理由は 1 つだけである必要があります
コードをコピー
クラス (JavaScript ではオブジェクトである必要があります)関連する動作は何を意味しますか?の近いセットが必要です。単一の責任に従うことの利点は、オブジェクトに多くの責任がカプセル化されている場合、1 つの責任を変更する必要があると、必然的にオブジェクトの他の責任のコードに影響を与えることになります。切り離すことで、責任ある各従業員がより柔軟に変更できるようになります。

しかし、オブジェクトの複数の動作が複数の責任を構成するのか、それとも 1 つの責任を構成するのかをどのようにして知るのでしょうか?書籍『オブジェクト デザイン: 役割、責任、およびコラボレーション』で提案されている役割ステレオタイプの概念を参照して決定できます。この概念では、責任を区別するために次の役割ステレオタイプが提案されています。

情報保持者 – このオブジェクトは保存するように設計されています。オブジェクトを作成し、オブジェクト情報を他のオブジェクトに提供します。
Structurer - このオブジェクトは、オブジェクトと情報の間の関係を維持するように設計されています。
Service Provider - このオブジェクトは、作業を処理し、他のオブジェクトにサービスを提供するように設計されています。
Controller - このオブジェクトは、一連のオブジェクトを制御するように設計されています。責任ある決定 タスク処理
コーディネーター - このオブジェクトは意思決定の処理作業を行わず、単に他のオブジェクトに作業を委任するだけです
インターフェイス - このオブジェクトは、システムのさまざまな部分で情報 (またはリクエスト) を変換するように設計されています
理解すると、これらの概念を使用すると、コードに複数の責任があるのか​​、それとも単一の責任があるのか​​を簡単に知ることができます。

コード例
このコード例は、ショッピング カートに商品を追加する方法を示しています。コードは次のとおりです。

コピーcode コードは次のとおりです。

function Product(id, description) {
this.getId = function () {
return id;
};
this.getDescription = function () {
return description;

function Cart(eventAggregator) {
var items = [ ];

this.addItem = function (item) {
items.push(item)
}

(function () {
var products = [新製品 (1, "スター・ウォーズ レゴ船"),
新製品 (2, "バービー人形"),
新製品 (3, "リモコン飛行機")],
カート = new Cart() ;

function addToCart() {
var productId = $(this).attr('id');
var product = $.grep(products, function ( x) {
return x.getId() == productId;
cart.addItem(product) = $(' ').html(product.getDescription()).attr('id-cart', product.getId()).appendTo("#cart"); >products.forEach(function (product) {
var newItem = $('
  • ').html(product.getDescription())
    .attr('id', product .getId())
    .dblclick(addToCart)
    .appendTo("#products")
    })();


    それぞれ 2 つの関数を宣言します。製品とカートの説明に使用されます。匿名関数の役割は、画面を更新してユーザーと対話することです。これはそれほど複雑な例ではありませんが、匿名関数には無関係な多くの役割が含まれています。見てみましょう。責任の数:

    まず、製品コレクションの宣言があります。
    次に、製品コレクションを #product 要素にバインドするコードがあり、イベント ハンドラーも追加します。ショッピングカートに追加するための
    3 番目に、Cart ショッピングカートを表示する機能があります
    4 番目に、商品アイテムをショッピングカートに追加して表示する機能があります
    コードのリファクタリング
    コードを独自のオブジェクトに格納できるように分解してみましょう。このために、Martinfowler のイベント アグリゲーター (Event Aggregator) 理論を参照して、オブジェクト間で通信するコードを処理します。
    まず、イベント集約関数を実装しましょう。この関数は 2 つの部分に分かれており、1 つはハンドラーのコールバック コードに使用され、もう 1 つはサブスクライブとパブリッシュに使用される EventAggregator です。イベント。コードは次のとおりです:




    コードをコピーします


    コードは次のとおりです:

    function Event(name) {
    var handlers = [];

    this.getName = function () {
    名前を返します。
    };

    this.addHandler = function (ハンドラー) {
    handlers.push(ハンドラー);
    };

    this.removeHandler = function (ハンドラー) {
    for (var i = 0; i < handlers.length; i ) {
    if (handlers[i] == ハンドラー) {
    handlers.splice(i, 1);
    休憩;
    }
    }
    };

    this.fire = function (eventArgs) {
    handlers.forEach(function (h) {
    h(eventArgs);
    });
    };
    }

    function EventAggregator() {
    var events = [];

    function getEvent(eventName) {
    return $.grep(events, function (event) {
    return event.getName() === イベント名;
    })[0];
    }

    this.publish = function (eventName,eventArgs) {
    var events = getEvent(eventName);

    if (!event) {
    event = new Event(eventName);
    events.push(イベント);
    }
    event.fire(eventArgs);
    };

    this.subscribe = function (eventName, handler) {
    var events = getEvent(eventName);

    if (!event) {
    event = new Event(eventName);
    events.push(イベント);
    }

    event.addHandler(ハンドラー);
    };
    }

    その後、我们来註製品对象、代码如下:
    复制代記入代码如下:

    function Product(id, description) {
    this.getId = function () {
    return id;
    };
    this.getDescription = function () {
    説明を返します;
    };
    }

    次に、Cart オブジェクト、このオブジェクトの addItem の関数を参照して、イベント itemAdded を配布し、その後 item をパラメータとして削除します。 >
    复制代码代码如下: function Cart(eventAggregator) {
    var items = [];

    this.addItem = function (item) {
    items.push(item);
    eventAggregator.publish("itemAdded", item);
    };
    }


    CartController は主にカート オブジェクトとイベント コマータを受け取り、阅itemAdded によって要素ポイントを追加し、productSelected イベントによって製品を追加します。 >
    复制代码

    代码如下: function CartController(cart,eventAggregator) { eventAggregator.subscribe("itemAdded", function (eventArgs) { var newItem = $('
  • ').html(eventArgs.getDescription()).attr('id-cart',eventArgs.getId()).appendTo ("#カート")
    });
    eventAggregator.subscribe("productSelected", function (eventArgs) {
    cart.addItem(eventArgs.product);
    });
    }


    リポジトリの目的は、データを取得し (ajax から取得できる)、その後 getdata を公開する方法です。复制代码


    代码如下:

    function ProductRepository() {
    var products = [new Product(1, "Star Wars Lego Ship"),
    新製品(2、「バービー人形」)、新製品(3、「リモコン飛行機」)]; this.getProducts = function () { 商品を返品する; } }

    ProductController では、onProductSelect メソッドの 1 つが定義されており、主に配布触発productSelected イベントです。forEach は主にデータを商品リストに固定するために使用されます。 >



    复制代码


    代码如下:

    function ProductController(eventAggregator, productRepository) {
    var products = productRepository.getProducts();
    function onProductSelected() { var productId = $(this).attr('id'); var product = $.grep(products, function (x) { return x.getId() == productId; })[0]; eventAggregator.publish("productSelected", { 製品: 製品
    });
    }

    products.forEach(function (product) {
    var newItem = $('
  • ').html(product.getDescription())
    .attr('id', product.getId())
    .dblclick(onProductSelected)
    .appendTo("#products")
    });
    }


    最後の安全関数:




    复制代码


    代码如下:

    (function () {
    var eventsAggregator = new EventAggregator(),
    cart = new Cart(eventAggregator),
    cartController = new CartController(cart,eventAggregator),
    productRepository = new ProductRepository(),
    productController = new ProductController(eventAggregator, productRepository)
    })();

    匿名関数のコードが削減されていることがわかります。オブジェクトのインスタンス化コード。このコードでは、情報を受け取ってアクションに渡すコントローラーの概念を導入しました。また、主にオブジェクトの表示を処理するために使用されるリポジトリーの概念も導入しました。リファクタリングの結果、オブジェクト宣言をたくさん書くことになりますが、利点は、表示データを表示する必要があり、コレクションを処理するために処理コレクションを変更する必要があるため、それぞれのオブジェクトが明確な責任を持つことです。結合度は非常に低いです。

    最終コード
    コードをコピー コードは次のとおりです:

    関数イベント(名前) {
    var handlers = [];

    this.getName = function () {
    return name;

    this.addHandler = function (ハンドラー) {
    handlers.push(handler);
    };

    this.removeHandler = function (ハンドラー) {
    for (var i = 0; i < handlers.length ; i ) {
    if (handlers[i] == ハンドラー) {
    break;
    }
    }; >
    this.fire = function (eventArgs) {
    handlers.forEach(function (h) {
    h(eventArgs);
    }); >
    function EventAggregator() {
    var events = [];

    function getEvent(eventName) {
    return $.grep(events, function (event) {
    return event .getName( ) === イベント名;
    })[0];

    this.publish = function (eventName,eventArgs) {
    var イベント = getEvent(eventName);

    if (!event) {
    event = new Event(eventName);
    }
    event.fire(eventArgs); };

    this.subscribe = function (eventName, handler) {
    var イベント = getEvent(eventName);

    if (!event) {
    event = new Event(イベント名);
    events.push(イベント);

    event.addHandler(ハンドラー);
    }

    関数説明) {
    this.getId = function () {
    return id
    };
    return description; }

    function Cart(eventAggregator) {
    var items = [];

    this.addItem = function (item) {
    items.push(item); eventAggregator.publish ("itemAdded", item);
    };
    }

    function CartController(cart,eventAggregator) {
    eventAggregator.subscribe("itemAdded", function (eventArgs) {
    var newItem = $('
  • ').html(eventArgs.getDescription()).attr('id-cart',eventArgs.getId()).appendTo("#cart ");
    });

    eventAggregator.subscribe("productSelected", function (eventArgs) {
    cart.addItem(eventArgs.product);
    });
    }

    function ProductRepository() {
    var products = [新製品(1, "スター・ウォーズ レゴ船"),
    新製品(2, "バービー人形"),
    新製品(3, "リモコン飛行機")];

    this.getProducts = function () {
    商品を返品する;
    }
    }

    function ProductController(eventAggregator, productRepository) {
    var products = productRepository.getProducts();

    function onProductSelected() {
    var productId = $(this).attr('id'); $.grep (products, function (x) {
    return x.getId() == productId;
    })[0];
    eventAggregator.publish("productSelected", {
    product: product
    });
    }

    products.forEach(function (product) {
    var newItem = $('
  • ').html(product .getDescription( ))
    .attr('id', product.getId())
    .dblclick(onProductSelected)
    .appendTo("#products")
    ; }

    (function () {
    var eventsAggregator = new EventAggregator(),
    cart = new Cart(eventAggregator),
    cartController = new CartController(cart,eventAggregator),
    productRepository = new ProductRepository(),
    productController = new ProductController(eventAggregator, productRepository)
    })();


    概要
    このリファクタリングの結果を見て、一部のブロガーは次のように思うかもしれません。本当にそんなに複雑にする必要があるのですか?と私は尋ねました。私が言えるのは、これを行うべきかどうかはプロジェクトの状況次第だということだけです。

    プロジェクトが非常に小規模でコードの量がそれほど多くない場合、実際にはそれほど複雑にリファクタリングする必要はありませんが、プロジェクトが非常に複雑な大規模プロジェクトや小規模なプロジェクトの場合は、プロジェクトが将来的に急速に成長する可能性がある場合は、将来のメンテナンスを容易にするために、初期段階で責任を分離するための SRP 原則を考慮する必要があります。
    このウェブサイトの声明
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

    ホットAIツール

    Undresser.AI Undress

    Undresser.AI Undress

    リアルなヌード写真を作成する AI 搭載アプリ

    AI Clothes Remover

    AI Clothes Remover

    写真から衣服を削除するオンライン AI ツール。

    Undress AI Tool

    Undress AI Tool

    脱衣画像を無料で

    Clothoff.io

    Clothoff.io

    AI衣類リムーバー

    Video Face Swap

    Video Face Swap

    完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

    ホットツール

    メモ帳++7.3.1

    メモ帳++7.3.1

    使いやすく無料のコードエディター

    SublimeText3 中国語版

    SublimeText3 中国語版

    中国語版、とても使いやすい

    ゼンドスタジオ 13.0.1

    ゼンドスタジオ 13.0.1

    強力な PHP 統合開発環境

    ドリームウィーバー CS6

    ドリームウィーバー CS6

    ビジュアル Web 開発ツール

    SublimeText3 Mac版

    SublimeText3 Mac版

    神レベルのコード編集ソフト(SublimeText3)

    フロントエンドのサーマルペーパーレシートのために文字化けしたコード印刷に遭遇した場合はどうすればよいですか? フロントエンドのサーマルペーパーレシートのために文字化けしたコード印刷に遭遇した場合はどうすればよいですか? Apr 04, 2025 pm 02:42 PM

    フロントエンドのサーマルペーパーチケット印刷のためのよくある質問とソリューションフロントエンド開発におけるチケット印刷は、一般的な要件です。しかし、多くの開発者が実装しています...

    誰がより多くのPythonまたはJavaScriptを支払われますか? 誰がより多くのPythonまたはJavaScriptを支払われますか? Apr 04, 2025 am 12:09 AM

    スキルや業界のニーズに応じて、PythonおよびJavaScript開発者には絶対的な給与はありません。 1. Pythonは、データサイエンスと機械学習でさらに支払われる場合があります。 2。JavaScriptは、フロントエンドとフルスタックの開発に大きな需要があり、その給与もかなりです。 3。影響要因には、経験、地理的位置、会社の規模、特定のスキルが含まれます。

    javascriptの分解:それが何をするのか、なぜそれが重要なのか javascriptの分解:それが何をするのか、なぜそれが重要なのか Apr 09, 2025 am 12:07 AM

    JavaScriptは現代のWeb開発の基礎であり、その主な機能には、イベント駆動型のプログラミング、動的コンテンツ生成、非同期プログラミングが含まれます。 1)イベント駆動型プログラミングにより、Webページはユーザー操作に応じて動的に変更できます。 2)動的コンテンツ生成により、条件に応じてページコンテンツを調整できます。 3)非同期プログラミングにより、ユーザーインターフェイスがブロックされないようにします。 JavaScriptは、Webインタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。

    JavaScriptを使用して、同じIDを持つArray要素を1つのオブジェクトにマージする方法は? JavaScriptを使用して、同じIDを持つArray要素を1つのオブジェクトにマージする方法は? Apr 04, 2025 pm 05:09 PM

    同じIDを持つ配列要素をJavaScriptの1つのオブジェクトにマージする方法は?データを処理するとき、私たちはしばしば同じIDを持つ必要性に遭遇します...

    Shiseidoの公式Webサイトのように、視差スクロールと要素のアニメーション効果を実現する方法は?
または:
Shiseidoの公式Webサイトのようにスクロールするページを伴うアニメーション効果をどのように実現できますか? Shiseidoの公式Webサイトのように、視差スクロールと要素のアニメーション効果を実現する方法は? または: Shiseidoの公式Webサイトのようにスクロールするページを伴うアニメーション効果をどのように実現できますか? Apr 04, 2025 pm 05:36 PM

    この記事の視差スクロールと要素のアニメーション効果の実現に関する議論では、Shiseidoの公式ウェブサイト(https://www.shisido.co.co.jp/sb/wonderland/)と同様の達成方法について説明します。

    Console.log出力の違い結果:なぜ2つの呼び出しが異なるのですか? Console.log出力の違い結果:なぜ2つの呼び出しが異なるのですか? Apr 04, 2025 pm 05:12 PM

    Console.log出力の違いの根本原因に関する詳細な議論。この記事では、Console.log関数の出力結果の違いをコードの一部で分析し、その背後にある理由を説明します。 �...

    JavaScriptは学ぶのが難しいですか? JavaScriptは学ぶのが難しいですか? Apr 03, 2025 am 12:20 AM

    JavaScriptを学ぶことは難しくありませんが、挑戦的です。 1)変数、データ型、関数などの基本概念を理解します。2)非同期プログラミングをマスターし、イベントループを通じて実装します。 3)DOM操作を使用し、非同期リクエストを処理することを約束します。 4)一般的な間違いを避け、デバッグテクニックを使用します。 5)パフォーマンスを最適化し、ベストプラクティスに従ってください。

    フロントエンド開発でVSCodeと同様に、パネルドラッグアンドドロップ調整機能を実装する方法は? フロントエンド開発でVSCodeと同様に、パネルドラッグアンドドロップ調整機能を実装する方法は? Apr 04, 2025 pm 02:06 PM

    フロントエンドのVSCodeと同様に、パネルドラッグアンドドロップ調整機能の実装を調べます。フロントエンド開発では、VSCODEと同様のVSCODEを実装する方法...

    See all articles