私は本を使用してJavaコードをリファクタリングする方法を学んでいる既存のコードのデザイン(第1版)の改善:リファクタリング。著者は、以下に示すリファクタリングを行い、彼は私には明確ではないそれをしなかった理由の説明を提供します。誰かが助けに私は説明を理解することはできますか?コードは、映画レンタルソフトウェアです。
public class Movie {
//Lets call these constants "priceCode".
public static final int CHILDRENS = 2;
public static final int REGULAR = 0;
public static final int NEW_RELEASE = 1;
//...more code here...
}
class Rental {
private Movie _movie;
private int _daysRented;
//...more code here...
}
リファクタリング前に:
class Rental...
double getCharge() {
double result = 0;
switch (getMovie().getPriceCode()) {
case Movie.REGULAR:
result += 2;
if (getDaysRented() > 2)
result += (getDaysRented() - 2) * 1.5;
break;
case Movie.NEW_RELEASE:
result += getDaysRented() * 3;
break;
case Movie.CHILDRENS:
result += 1.5;
if (getDaysRented() > 3)
result += (getDaysRented() - 3) * 1.5;
break;
}
return result;
}
私たちは、既存のMovieクラスに上記の方法コードを移動します。
リファクタリングAFTER:
class Movie...
double getCharge(int daysRented) {
double result = 0;
switch (getPriceCode()) {
case Movie.REGULAR:
result += 2;
if (daysRented > 2)
result += (daysRented - 2) * 1.5;
break;
case Movie.NEW_RELEASE:
result += daysRented * 3;
break;
case Movie.CHILDRENS:
result += 1.5;
if (daysRented > 3)
result += (daysRented - 3) * 1.5;
break;
}
return result;
}
AUTHOR'S説明:
他のオブジェクトの属性に基づいてスイッチを行うには悪い考えです。あなたはswitchステートメントを使用する必要がある場合、それはあなた自身のデータではなく、他の誰かの上になければなりません。
このために、仕事に、私はもちろん、レンタルからのデータである、レンタルの長さに合格しなければなりませんでした。この方法は、効果的にデータの二枚、レンタルの長さや映画の種類を使用します。なぜ私はレンタルに映画にレンタルの長さではなく、映画の型を渡すことを好むのですか?提案された変更は、すべての新しいタイプを追加する方法についてであるため、それはです。タイプ情報は、一般的に、より揮発性である傾向があります。私は映画の種類を変更した場合、私は少なくとも波及効果をしたいので、私は映画の中に電荷を計算することを好みます。
私の質問に:
なぜそれが別のオブジェクトの属性に基づいてスイッチを行うには悪い考えですか?
これらの事は本当に「型情報は、一般的に揮発性である傾向がある」と「少なくとも波及効果(達成された)」とは何を意味するのですか?(揮発性およびリップル)これらのあいまいな言葉は明らかにこのリファクタリングの利点を説明していません。
PSは -これは、最終的なコードではありませんのでご注意ください。より多くの本の中で、後にリファクタリングがあります。私はこれが古い1990本であることを知っています。この本は、今日でも役立つことができ、コードの設計に関するアイデアやコンセプトをたくさん持っているようそれにもかかわらず、それが見えます。しかし、私はこの本はまた、2020年になると確信してどのくらい助けていないです、この本の最新版、リファクタリング:既存のコード(第2版)の設計を改善するには、私は知らないどのJavascriptを使用しています。
なぜそれが別のオブジェクトの属性に基づいてスイッチを行うには悪い考えですか?
その属性の種類が変更された場合ので、あなたは自分のコードに変更を加える必要があります。種類が場合Movie.priceCode
から切り替えられたint
とenum
、あなたはまた、変更コードになりますRental
。しかし、あなたは、あなたに価格計算を移動しMovie
、あなたがの種類を変更することができるよりもMovie.priceCode
影響を与えずRental
。
これらの事は本当に「型情報は、一般的に揮発性である傾向がある」と「少なくとも波及効果(達成された)」とは何を意味するのですか?(揮発性およびリップル)これらのあいまいな言葉は明らかにこのリファクタリングの利点を説明していません。
あなたは(HBOシリーズ、ディズニーシリーズ、などなど)ムービーに、より価格のコードを追加することを決定した場合、あなたは両方の変化加える必要がありますMovie
し、Rental
クラスを。あなたが使用していない場合でも、Movie.priceCode
内部のRental
、あなたは、変更する必要はありませんRental
削除しても、すべてのクラスpriceCode
のムービーからか、名前を変更したり、そのタイプを変更します。この場合、変更のローカライズスコープに助けをリファクタリング。あなたがコードを書いているとMovie
、別のチームがために、コードを書きRental
、あなたはより多くの価格タイプを追加することにしました。今、あなたはおそらくあなたの新しいバージョンで新しい成果物を構築、計算のために、彼らは値ロジックを提供し、あなたがより多くの種類を追加したことを、他のチームに通知する必要があるMovie
クラス。しかし、あなたは唯一のそれらの方法を提供する場合getCharge(daysRented)
あなたは、通知のオーバーヘッドなしでどんな新しいタイプを追加することができます。