[ロック解除新しい姿勢は]場合-else`、我々があれば打倒しなければならない `によって支配されているの恐怖を思い出す - 他

序文

[ロック解除新しい姿勢]弟のデイ、あなたはコードを最適化する必要がある
記事は単に、言ったの前に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);
    }
}
复制代码

静的内部シングルトンクラスの一種、実現のシングル実施の形態では、この記事が焦点ではありません理解していない場合、それは自己することができ google

私たちは、その後、作成に着手したStrategyFactoryファクトリクラスを。StrategyFactoryは、ここで私が使用しています静态内部类单例コンストラクタはあなたが必要とすることを初期化するとき、Strategyと入れlistmapここでの変換である“灵魂”嘘。

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“优雅处理”が間違っている場合、私たちは一緒に学習の交換を歓迎し、アイデア。

おすすめ

転載: juejin.im/post/5def654f51882512302daeef