[リフォーム2盤]11API再構築

6055 ワード

11.1クエリー関数と変更関数の分離


浮動小数点効果のある関数と浮動小数点効果のない関数は明確に区別したほうがいい.

11.2パラメトリック関数


2つの論理が非常に類似しており、異なる文字値にすぎない場合、異なる値のみをパラメータとして処理する方法は、重複を解決することができる.
// bad case
function tenPercentRaise(aPerson) {
	aPerson.salary = aPerson.salary * 1.1;
}

function fivePercentRaise(aPerson) {
	aPerson.salary = aPerson.salary * 1.05;
}

// good case
function raise(aPerson, factor) {
	aPerson.salary = aPerson.salary * (1 + factor);
}

11.3フラグパラメータの削除


フラグパラメータ:呼び出し関数呼び出しロジックの一方を選択するための転送パラメータ.
// bad case
function  setDimension(name,value) {
	if (name === "height") {
    	this._height = value;
        return ;
    }
    if (name === "width") {
    	this._width = value;
        return;
    }
}

// good cse
function setHeight(value) {
	this._height = value;
}

function setWidth(value) {
	this._width = value;
}

11.4オブジェクト全体


夏郎のレコードから2つ以上の値を得て、それを買収側に渡すなら、レコード全体を買収側に渡すのが望ましい.
ただし,オブジェクトからいくつかの値を得た後,これらの値だけで何らかの操作が可能な論理であれば,オブジェクトに入れなければならない悪臭をユーザに伝えるものと見なすべきである.
// bad case
const low = aRoom.daysTempRange.low;
const high = aRoom.daysTempRange.high;
if (aPlan.withRange(low, high))

// good case
if (aPlan.withRange(aRoom.daysTempRange))

11.5パラメータをクエリー関数に変換

// bad case
availableVacation(anEmployee, anEmployee.grade);

function availableVacation(anEmployee, grade) {
// 연휴 계산
}

// good case
function availableVacation(anEmployee) {
	const grade = anEmployee.grade;
}
パラメータを削除すると、値を決定する責任主体が変わります.
パラメータがある場合、意思決定主体は呼び出し者であり、パラメータがない場合、意思決定主体は呼び出し者である.
パラメータをクエリー関数に変更することはできません.
パラメータを削除すると、呼び出された関数に望ましくない依存性が発生します.

11.6クエリー関数をパラメータに置き換える


関数に配置に不適切な参照がある場合は、パラメータに置き換えます.
// bad case
targetTemparature(aPlan)

function targetTemparature(aPlan) {
	currentTemparature = thermostat.currentTemparature;
}

// good case
targetTemparature(aPlan, thermostat.currentTemparature);

function targetTemparature(aPlan, currentTemparature) {

}
≪参照の透過性|Reference Transparency|oem_src≫:同じ値が渡されると、毎回同じ結果が得られます.

11.7ポッターを取り外します

// bad case
class Person {
	get name() {}
   	set name(aString) {}
}

// good case
class Person {
	get name() {}
}
setterメソッドがあることを示します->フィールドは変更できます
フィールドがオブジェクトの作成後に変更されない場合は、テナントは提供されません.(変わらないように)
どちらの場合もサーバを削除する必要があります
1.訪問者メソッドのみでフィールドを処理したい場合
2.クライアントが生成したSearchスクリプトを使用してオブジェクトを作成する場合
->スクリプトが完了しても、オブジェクトのフィールドまたはすべては変更されません.

11.8ジェネレータをファクトリ関数に置き換えます

// bad case
const leaEngineer = new Employee(document.leadEngineer, 'E');

// good case
const leaEngineer = new createEngineer(document.leadEngineer);

function createEngineer(name) {
	return new Employee(name, 'E');
}

11.9関数をコマンドに置き換える


11.10コマンドを関数に変換


11.9と11.10は逆の再包装概念で、読みながら読むと分かりやすい.
関数が特定のタスクを実行し、論理が複雑でない場合は、11.10コマンドを関数に変換できます.
論理が複雑で、関数で複数の作業を行う場合は、11.9関数をコマンドに変換する方法が適切です.
ソースコードの表示と理解.

11.11変更された値を返します。

// bad case
let totalAscent = 0;
calculateAsscent();

function calculateAsscent() {
	for(let i=1; i<points.length; i++) {
    	const verticalChange = points[i].elevation - points[i-1].elevation;
        totalAscent += (verticalChange > 0) ? verticalChange : 0;
    }
}
// good case
const totalAscent = calculateAsscent();
function calculateAsscent() {
	let result = 0;
	for(let i=1; i<points.length; i++) {
    	const verticalChange = points[i].elevation - points[i-1].elevation;
        result += (verticalChange > 0) ? verticalChange : 0;
    }
    return result;
}
変数の値->関数を事前に分解していない場合は、変数を上に宣言し、次の関数で宣言した変数の値を変更しない限り、変数の値がどこで変化するかを見つけるのは難しいです.
△個人的には、再構築段階に比べて、コードの作成から採用すべき方法だと思います.

11.12エラーコードを例外に置換


例外は想定外の動作時のみ使用できます.(正常な動作カテゴリでない場合)
正常に動作しないと判断した場合は、例外ではなくエラーをチェックし、プログラムを正常なストリームに戻す必要があります.(ランダム投げ処理X)

11.13異常を「事前検査」に変更


例外は11.12のような意外な動作の場合にのみ使用します.
例外を無条件に投げ出すのではなく、予想される特定の状況で条件をチェックします.
// bad case
double getValueForPeriod (int periodNumber) {
	try {
    	return values[periodNumber];
    } catch(ArrayIndexOutOfBoundsException e) {
    	return 0;
    }
}
// good case
double getValueForPeriod (int periodNumber) {
	return (periodNumber >= values.length) ? 0 : values[periodNumber];
}
ソースコード
https://github.com/yeoj1n/JS-study/blob/master/refactoring-study/chapter11/API%EB%A6%AC%ED%8C%A9%ED%84%B0%EB%A7%81.js