序文
[ロック解除新しい姿勢]弟のデイ、あなたはコードを最適化する必要がある
記事は単に、言ったの前にif-else
、使用することができ卫语句
、最適化のために。しかし、実際の開発では、多くの場合ではないシンプルなif-else
構造で、我々は通常、不经意间
次のコードを記述します。
-------------------- 理想中的 if-else --------------------
public void today() {
if (isWeekend()) {
System.out.println("玩游戏");
} else {
System.out.println("上班!");
}
}
-------------------- 现实中的 if-else --------------------
if (money >= 1000) {
if (type == UserType.SILVER_VIP.getCode()) {
System.out.println("白银会员 优惠50元");
result = money - 50;
} else if (type == UserType.GOLD_VIP.getCode()) {
System.out.println("黄金会员 8折");
result = money * 0.8;
} else if (type == UserType.PLATINUM_VIP.getCode()) {
System.out.println("白金会员 优惠50元,再打7折");
result = (money - 50) * 0.7;
} else {
System.out.println("普通会员 不打折");
result = money;
}
}
//省略 n 个 if-else ......
复制代码
それは、私たちはリコール、類似したコードを書かれていると言っても過言ではないif-else
恐怖が支配し、私たちはしばしば何も、あるいは何も始まります。
ここでは、複合体の開発における私の経験を共有するためif-else
のステートメントの“优雅处理”
アイデアを。間違っている場合は、私たちは一緒に学習の交換を歓迎します。
需要
そのような需要があると仮定します。
ユーザーの消費電力供給システム、满1000
ユーザーのVIPレベルに基づいて金額は、割引を受けます。
VIPレベルが最終使用者のコストを計算するために、ユーザーに基づきます。
- 普通のメンバーは割引しないでください
- シルバー会員特典50元
- ゴールド20%
- プラチナ会員はリゾートオフ50、30%に利益をもたらします
コーディング
private static double getResult(long money, int type) {
double result = money;
if (money >= 1000) {
if (type == UserType.SILVER_VIP.getCode()) {
System.out.println("白银会员 优惠50元");
result = money - 50;
} else if (type == UserType.GOLD_VIP.getCode()) {
System.out.println("黄金会员 8折");
result = money * 0.8;
} else if (type == UserType.PLATINUM_VIP.getCode()) {
System.out.println("白金会员 优惠50元,再打7折");
result = (money - 50) * 0.7;
} else {
System.out.println("普通会员 不打折");
result = money;
}
}
return result;
}
复制代码
プレゼンテーションを容易にするために、コードは、私はシンプルに実現し、実際にif - else
されます复杂的逻辑
充電します。機能的には、基本的な完了が、私のような人々がそれの上にコードを持っているため、コードの品質に直接見て耐えることができませんでした。私たちは、開始优化
私たちの第一版代码
バー。
考えます
コードの上を参照してください、スマート友人最初に考えたのは、これは典型的なではないということです策略模式
、それ?
あなたが賢い少年だ、我々はコードにそれを最適化するための戦略モードの使用を探ります。
戦略モード
戦略パターンとは何ですか?
何人かの友人はまだ不明で、戦略パターン何です。Strategyパターンは、一連のアルゴリズムを定義し、それらを1つずつ置くことです封装
アップ、そして相互にそれらを作ります替换
。
例えば、上記の要望、返利
そこに打折
、そこに折上折
、というように。アルゴリズム自体は親切です策略
。そして、これらのアルゴリズムのそれぞれができ替换
、例えば、私がしたい今日は白银会员优惠50
、明日を交換することができます白银会员打9折
。
彼はそんなに、それはより良い、より実際のコーディングされました。
コーディング
public interface Strategy {
// 计费方法
double compute(long money);
}
// 普通会员策略
public class OrdinaryStrategy implements Strategy {
@Override
public double compute(long money) {
System.out.println("普通会员 不打折");
return money;
}
}
// 白银会员策略
public class SilverStrategy implements Strategy {
@Override
public double compute(long money) {
System.out.println("白银会员 优惠50元");
return money - 50;
}
}
// 黄金会员策略
public class GoldStrategy implements Strategy{
@Override
public double compute(long money) {
System.out.println("黄金会员 8折");
return money * 0.8;
}
}
// 白金会员策略
public class PlatinumStrategy implements Strategy {
@Override
public double compute(long money) {
System.out.println("白金会员 优惠50元,再打7折");
return (money - 50) * 0.7;
}
}
复制代码
私たちは、の定義に来るStrategy
インタフェース、およびインタフェースを実装する4つのサブクラスを定義します。対応するにはcompute
、ポリシーロジック自体を会計の実現方法。
private static double getResult(long money, int type) {
double result = money;
if (money >= 1000) {
if (type == UserType.SILVER_VIP.getCode()) {
result = new SilverStrategy().compute(money);
} else if (type == UserType.GOLD_VIP.getCode()) {
result = new GoldStrategy().compute(money);
} else if (type == UserType.PLATINUM_VIP.getCode()) {
result = new PlatinumStrategy().compute(money);
} else {
result = new OrdinaryStrategy().compute(money);
}
}
return result;
}
复制代码
その後、対応するgetResult
方法によれば、type
対応するユーザにVIPを交換してください策略
。ここでは、コードの繰り返し呼び出しが行われているcompute
、我々はさらに最適化することを試みることができます。
private static double getResult(long money, int type) {
if (money < 1000) {
return money;
}
Strategy strategy;
if (type == UserType.SILVER_VIP.getCode()) {
strategy = new SilverStrategy();
} else if (type == UserType.GOLD_VIP.getCode()) {
strategy = new GoldStrategy();
} else if (type == UserType.PLATINUM_VIP.getCode()) {
strategy = new PlatinumStrategy();
} else {
strategy = new OrdinaryStrategy();
}
return strategy.compute(money);
}
复制代码
私はまだ覚えている最初の記事がでてくる卫语句
こと?私たちは、お金<早期復帰の1000年のケースを置くためにここにいます。もっと着目满1000逻辑
、あなたはまた、不要なインデントを減らすことができます。
ポンダー
私はかつての戦略パターンより良いこれよりもと思いました。コードの最適化は、すでにこれに思いました。
しかし、恐ろしいことがありif-else
、まだ存在している:)
私は、ポリシーモードを排除する方法を確認するために、たくさんの本を読んでしよう if-else
本の中でメソッドのほとんどは、工場出荷時のモード+シンプルな戦術を使用することです。if - else
するスイッチswitch
のみファクトリメソッドを作成します。
しかし、これは、これまで私が効果を達成するために何をしたいからダウンしています if - else
ある日の夜、私の兄グループのシェアまでJava8
広いからヒントは、新しい世界を開きます。
工場+戦略
public interface Strategy {
double compute(long money);
// 返回 type
int getType();
}
public class OrdinaryStrategy implements Strategy {
@Override
public double compute(long money) {
System.out.println("普通会员 不打折");
return money;
}
// 添加 type 返回
@Override
public int getType() {
return UserType.SILVER_VIP.getCode();
}
}
public class SilverStrategy implements Strategy {
@Override
public double compute(long money) {
System.out.println("白银会员 优惠50元");
return money - 50;
}
// type 返回
@Override
public int getType() {
return UserType.SILVER_VIP.getCode();
}
}
....省略剩下 Strategy
复制代码
私たちは、新たな戦略の最初getType
のための方法标示
のポリシーtype
値。コードは比較的簡単ですが、あまりにも多くの説明はありません
public class StrategyFactory {
private Map<Integer, Strategy> map;
public StrategyFactory() {
List<Strategy> strategies = new ArrayList<>();
strategies.add(new OrdinaryStrategy());
strategies.add(new SilverStrategy());
strategies.add(new GoldStrategy());
strategies.add(new PlatinumStrategy());
strategies.add(new PlatinumStrategy());
// 看这里 看这里 看这里!
map = strategies.stream().collect(Collectors.toMap(Strategy::getType, strategy -> strategy));
/* 等同上面
map = new HashMap<>();
for (Strategy strategy : strategies) {
map.put(strategy.getType(), strategy);
}*/
}
public static class Holder {
public static StrategyFactory instance = new StrategyFactory();
}
public static StrategyFactory getInstance() {
return Holder.instance;
}
public Strategy get(Integer type) {
return map.get(type);
}
}
复制代码
静的内部シングルトンクラスの一種、実現のシングル実施の形態では、この記事が焦点ではありません理解していない場合、それは自己することができ
私たちは、その後、作成に着手したStrategyFactory
ファクトリクラスを。StrategyFactoryは、ここで私が使用しています静态内部类单例
コンストラクタはあなたが必要とすることを初期化するとき、Strategy
と入れlist
にmap
。ここでの変換である“灵魂”
嘘。
toMap
のは、見てみましょうJava8
文法のヒントを。
通常の状況下で、我々はマニュアル、リストをトラバースput
地図へ。
-------------- before -----------------
map = new HashMap<>();
for (Strategy strategy : strategies) {
map.put(strategy.getType(), strategy);
}
-------------- after Java8 -----------------
map = strategies.stream().collect(Collectors.toMap(Strategy::getType, strategy -> strategy));
复制代码
toMap
最初のパラメータは、地図に対応する、機能でkey
、2番目のパラメータは機能、戦略である- >戦略、左のstrategy
各戦略、右が横断戦略でstrategy
対応するマップであるvalue
値。
場合は分からない
Java8
友人は文法、それは強く見ることをお勧めしますJava8 实战
「」本は詳細に記述しLambda
、表現をStream
、このような文法など。
効果
private static double getResult(long money, int type) {
if (money < 1000) {
return money;
}
Strategy strategy = StrategyFactory.getInstance().get(type);
if (strategy == null){
throw new IllegalArgumentException("please input right type");
}
return strategy.compute(money);
}
复制代码
これまでのところ、ファクトリクラスを通じて、私たちの中にgetResult()
入ってくるに基づいてコールの時type
、あなたは相当に得ることができますStrategy
いいえひどいif-else
声明ありません。
Sahua Sahuaエンド:)
フォロー
その後のコードの最適化は、Javaプロジェクトならば、あなたは試すことができ自定义注解
、注釈戦略の実装クラスを。
これは、ファクトリクラスのリストを追加するには、元の必要性を簡素化しますStratey 策略
。
遂に
これは、複合体の開発に遭遇したすべてのIであるif-else
文“优雅处理”
が間違っている場合、私たちは一緒に学習の交換を歓迎し、アイデア。