JavaScriptシリーズを深く理解する(7) S.O.L.I.Dの開閉五原則 OCP_javascriptスキル
May 16, 2016 pm 05:57 PMはじめに
この章で説明するのは、S.O.L.I.D の 5 つの原則である Open/Closed Principle OCP (The Open/Closed Principle) の JavaScript 言語実装の第 2 部です。
開始と終了の原則の説明は次のとおりです。
ソフトウェア エンティティ (クラス、モジュール、関数など) は拡張に対してオープンである必要がありますが、変更に対してはクローズされている必要があります。など)は、拡張に対してオープンであり、変更に対してクローズである必要があります。つまり、ソフトウェア エンティティは変更せずに拡張する必要があります。
コードをコピー
拡張にオープンとは、新しいニーズが生じたときに、既存のモデルを拡張して目標を達成できることを意味します。端的に言えば、「変更をクローズ」とは、エンティティへの変更が許可されていないことを意味します。さまざまな動作を実行する必要があるこれらのエンティティは、変更を加えずにさまざまな変更を実行できるように設計されており、その原則により、プロジェクトのメンテナンスが最小限で容易になります。コード。
英語原文: http://freshbrewedcode.com/derekgreer/2011/12/19/solid-javascript-the-openclosed-principle/
問題コード
直感的に説明するために、例を挙げてみましょう例として、下位コードは質問リストを動的に表示するコードです (開始と終了の原則は使用されません)。
var AnswerType = {
Choice: 0,
Input: 1
};
// 質問エンティティ
関数 question(label, AnswerType, Choices) {
return {
label: label,
answerType:answerType,
choices:choices // ここでの選択肢はオプションのパラメータです
}
}
var view = (function () {
// 質問をレンダリングします
function renderQuestion(target, question) {
var questionWrapper = document.createElement('div');
questionWrapper.className = 'question';
var questionLabel = document.createElement('div' ) ;
questionLabel.className = 'question-label';
var label = document.createTextNode(question.label);
var = document.createElement( ' div');
answer.className = 'question-input'
// ドロップダウン メニューと入力ボックスのそれぞれに応じて異なるコードを表示します
if (question.answerType == = AnswerType.Choice) {
var input = document.createElement('select');
var len = question.choices.length;
for (var i = 0; i
option.text = question.choices[i];
option.value = question.choices[i];
}
}
else if (question.answerType === AnswerType.Input) {
var input = document.createElement('input'); 'テキスト';
}
questionWrapper.appendChild(questionLabel);
target.appendChild(questionWrapper); >}
return {
// 表示するためにすべての質問リストをスキャンします
render: function (target,questions) {
for (var i = 0; i <questions.length; i ) {
renderQuestion(ターゲット, 質問[i]);
}
})();
varquestion('過去 30 日以内に使用したタバコ製品はありますか?', AnswerType.Choice, ['はい', 'いいえ']),
question('現在使用している薬は何ですか?', AnswerType.Input)
];
var questionRegion = document.getElementById('questions');
view.render(questionRegion,questions);
上記のコードでは、ビュー オブジェクトに To が含まれています。質問リストを表示するには、質問の種類に応じて異なる表示方法が使用されます。質問には、ラベル、質問の種類、選択肢のオプション (選択タイプの場合) が含まれます。質問の種類が選択の場合は、オプションに基づいてドロップダウン メニューを生成します。質問の種類が入力の場合は、単に入力入力ボックスを表示します。
このコードには制限があります。つまり、別の質問タイプを追加する場合は、renderQuestion の条件ステートメントを再度変更する必要があり、これは明らかに開始と終了の原則に違反します。
コードのリファクタリング
このコードをリファクタリングして、新しい質問タイプが表示されたときに、ビュー オブジェクト内のコードを変更せずに、ビュー オブジェクトのレンダリング機能を拡張できるようにします。
最初に一般的な質問を作成しますCreator 関数:
コードは次のとおりです:
function questionCreator(spec, my) {
var that = {};
my.label =
my. renderInput = function () {
throw "notimplemented";
// ここでは renderInput が実装されていません。主な目的は、それぞれの問題タイプの実装コードでメソッド全体をカバーすることです
}; 🎜>that.render = function (target) {
var questionWrapper = document.createElement('div');
questionWrapper.className = 'question';
var questionLabel = document.createElement('div' );
questionLabel.className = 'question-label';
var label = document.createTextNode(spec.label);
var = my.renderInput( );
// render メソッドは同じ大まかで合理的なコードです
// 唯一の違いは上記の文です my.renderInput()
// 質問タイプが異なれば実装も異なるため
questionWrapper .appendChild(questionLabel );
questionWrapper.appendChild(answer);
return that;
このコードは 1 つの質問をレンダリングしますが、実装されていない renderInput メソッドを提供しているため、他の関数がそれをオーバーライドしてさまざまな質問タイプを使用できるようになります。
コードをコピーします
コードは次のとおりです:
option.text = spec.choices[ i];
option.value = spec.choices[i];
入力を返します;
>}
function inputQuestionCreator( spec) {
var my = {},
that = questionCreator(spec, my)
//入力型の RenderInput 実装
my.renderInput = function () {
var input = document.createElement('input');
入力を返します;
}
choiceQuestionCreator 関数と inputQuestionCreator 関数は、それぞれドロップダウン メニューと入力ボックスの renderInput 実装に対応し、統合された questionCreator(spec, my) を内部で呼び出し、そのオブジェクト (同じタイプです)。
ビュー オブジェクトのコードは非常に固定されています。
コードをコピー
コードは次のとおりです:
var view = {
render: function(target ,questions) {
target.appendChild(questions[i].render());
>}
}; コードをコピー
コードは次のとおりです:
varquestions = [
choiceQuestionCreator({
label: '範囲内でタバコ製品を使用しましたか?過去 30 日間?',
choices: ['Yes', 'No']
inputQuestionCreator({
label: '現在使用している薬は何ですか?'
コードをコピーします
コードは次のとおりです:
var questionRegion = document.getElementById('questions');
view.render(questionRegion,questions); 🎜>
リファクタリング後の最終コード

人気の記事

人気の記事

ホットな記事タグ

メモ帳++7.3.1
使いやすく無料のコードエディター

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

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

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

ホットトピック









