最小限のコストでプロジェクトの「たわごと」コードの可読性をすばやく改善する方法(Momはライブラリの削除や暴走について心配する必要がなくなりました)

序文

この章では、主にコードの可読性を高める方法を学びます。ある人は、自分の研究デザインパターンの中で、他のモード笑われると思っていたモデルが一番いいと言っていたので、すぐに学べると思うことが多いのですが、実際の使い方は覚えていませんでした。オンラインの障害を修正することを恐れて、私がそれに遭遇してもあえて変更しないでください。結局、書くことと書くことはビジネスプログラミングに戻ります。

著者:チーウェイ
リンク付きのvivo :https://juejin.im/post/6844904047397322759

テキスト

最も簡単な例として、誰もがAliのJavaコーディング仕様を見たことがあるはずです。ほとんどの人は、AliのJavaコード検出プラグインをインストールしていることもあります。その1つは、関数行の数が特定の範囲を超えるとプロンプトが表示されることです。警告関数が長すぎて最適化が必要であることを示します。多くの人はその理由を理解していません。Aliの公式の理由でさえ、ほとんどの人はコンピューターの1つの画面にn行のコードしか表示できないため、ここではこの関数の行数の検証を増やす必要があります。 。

実は、長年働いた後の私の気持ちは、上記の理由はとてつもないものだと思いますが、短い関数を最適化する必要はありませんか?次の関数を見ることができます。この関数も非常に短いですが、読みやすさは良くありません。

public class CustomList {

    private boolean readOnly;

    //默认的数组实际存储的元素个数 为0,
    private int size;

    //默认数组的长度为5
    private Object[] elements = new Object[5];

    /**
     *  只读模式下 才可以添加元素,
     *  如果数组长度足够 那么就直接往后面添加一个元素
     *  如果数组长度不够 则将数组的长度增加10
     *  然后再进行赋值
     *
     * @param element
     */
    public void add(Object element) {
        if (!readOnly) {
            int newSize = size + 1;
            if (newSize > elements.length) {
                Object[] newElements = new Object[elements.length + 10];
                for (int i = 0; i < size; i++) {
                    newElements[i] = elements[i];
                }
                elements = newElements;
            }
            elements[size++] = element;
        }

    }

}

最適化の最初のステップ:

public void add(Object element) {
        //只读模式就啥也不做
        if (readOnly) {
            return;
        }
        if (atCapacity()) {
            Object[] newElements = new Object[elements.length + 10];
            for (int i = 0; i < size; i++) {
                newElements[i] = elements[i];
            }
            elements = newElements;
        }
        elements[size++] = element;
    }

    //是否需要扩容
    private boolean atCapacity() {
        int newSize = size + 1;
        return newSize > elements.length;
    }

2番目のステップ:

 public void add(Object element) {
        //只读模式就啥也不做
        if (readOnly) {
            return;
        }
        if (atCapacity()) {
            grow();
        }
        addElement(element);
    }

    //是否需要扩容
    private boolean atCapacity() {
        int newSize = size + 1;
        return newSize > elements.length;
    }

    //扩容
    private void grow() {
        Object[] newElements = new Object[elements.length + 10];
        for (int i = 0; i < size; i++) {
            newElements[i] = elements[i];
        }
        elements = newElements;
    }

    //增加一个元素
    private void addElement(Object element) {
        elements[size++] = element;
    }

これで、addメソッドには5行のコードしかありません。初版と比べると、読みやすさが大きく異なります。

クラスにパブリックメソッドが非常に多くプライベートメソッドが非常に少ない場合は、最適化の余地があるはずです。

システムのシンプルさを維持したい場合は、上記の組み合わせメソッドを可能な限り適用して、詳細にリファクタリングし、複雑なパブリックメソッドを単純なプライベートメソッドに再構築し、最後にパブリックメソッドを公開する必要があります。プライベートへの呼び出しのみがあります。ビジネスプロセスのメソッド

別の問題を見ていきましょう。多くの古いプロジェクトでは、Shishanコードの最大の特徴は、他に多すぎることです。多くの人々は、この問題を解決できる戦略モードと呼ばれる方法があることを知っていますが、恐れています。開始します。たとえば、Shishanコードのifelseをターゲットにする方法を体験してみましょう。

この記事のPayResultクラスを使用して、支払い結果のポイントを取得するメソッドを追加します。結局のところ、eコマースで物を買うときは常にポイントを取り戻す必要があります。

 //获取积分
    public double getIntegral() {
        //银联支付 按照1.5实际支付额度 返回积分
        if (payChannel instanceof BankChannel) {
            return paymentValue * 1.5;
        } else if (payChannel instanceof WxChannel) {
            //微信支付就按照实际支付额度两倍,然后减去券的金额
            return paymentValue * 2 - couponValue;
        } else if (payChannel instanceof AliPayChannel) {
            //支付宝支付*2 ,然后还可以加上花呗支付的积分 马爸爸牛逼
            return paymentValue * 2 + loanValue * 1;
        }
        return 0;
    }

このようなコードプロジェクトは確かに珍しいことではありません。次に、リスクなしで成熟したシステムでこのコードを最適化する方法を見てみましょう。読みやすさと保守性を拡張します。結局のところ、多くの人は他の方法で減らす方法を知っていますが、実際にはそれを行うことができないことがよくあります。彼らはそれを行う方法を知らず、あえてそれをしません。

最初に統合戦略クラスを取得しましょう。

//积分策略
public class IntegralStrategy {
    public double getIntegral() {
        return 0;
    }
}

次に、実際の統合アルゴリズムロジックをこの戦略クラスに入れます

明らかに、まだいくつかのパラメーターが必要です。そうでない場合、これらのロジックで参照する必要のある変数が見つかりません。外部参照を渡します。

//积分策略
public class IntegralStrategy {
    public double getIntegral(PayResult payResult) {
        //银联支付 按照1.5实际支付额度 返回积分
        if (payResult.getPayChannel() instanceof BankChannel) {
            return payResult.getPaymentValue() * 1.5;
        } else if (payResult.getPayChannel() instanceof WxChannel) {
            //微信支付就按照实际支付额度两倍,然后减去券的金额
            return payResult.getPaymentValue() * 2 - payResult.getCouponValue();
        } else if (payResult.getPayChannel() instanceof AliPayChannel) {
            //支付宝支付*2 ,然后还可以加上花呗支付的积分 马爸爸牛逼
            return payResult.getPaymentValue() * 2 + payResult.getLoanValue() * 1;
        }
        return 0;
    }
}

次に、PayResultメインクラスを変更します。

  //获取积分
    public double getIntegral() {

        return integralStrategy.getIntegral(this);
    }

//注意这个时候我们的全包构造函数 变成了private
    private PayResult(PayChannel payChannel, Date payDate, Double totalValue, Double paymentValue, Double couponValue, Double loanValue) {
        this.payChannel = payChannel;
        this.payDate = payDate;
        this.totalValue = totalValue;
        this.paymentValue = paymentValue;
        this.couponValue = couponValue;
        this.loanValue = loanValue;
        //也仅仅在这个构造函数 这里增加了一行代码
        integralStrategy=new IntegralStrategy();
    }    

この時点で、予備的なデカップリング作業は完了しましたが、全体として、elseロジックが完全に削除されていない場合は、場所を移動して、最適化を続けます。

ここで注意する必要があります。ifelseロジックがメインクラスのパラメーターをあまり必要としない場合、パラメーターが直接渡される限り、メインクラス参照を直接渡す必要はありません。ここではデモンストレーションの便宜上です。 、メインクラスのClassをパラメータとして直接渡します。

メインクラスへの参照を渡さずにパラメータのみを渡すことには利点があります。コンテキストクラスとこれらのストラテジークラスの間の最小結合のみが含まれます。

それ以外の場合は最初に削除します

//积分策略
public abstract class IntegralStrategy {
    abstract double getIntegral(PayResult payResult);
}
public class AliPayIntegralStrategy extends IntegralStrategy {
    @Override
    double getIntegral(PayResult payResult) {
        return payResult.getPaymentValue() * 2 + payResult.getLoanValue() * 1;
    }
}
public class UnionPayIntegralStrategy extends IntegralStrategy {
    @Override
    double getIntegral(PayResult payResult) {
        return payResult.getPaymentValue() * 1.5;
    }
}
public class WxPayIntegralStrategy extends IntegralStrategy {
    @Override
    double getIntegral(PayResult payResult) {
        return payResult.getPaymentValue() * 2 - payResult.getCouponValue();
    }
}

次に、PayResultの構築方法を変更します。

 //银联支付 注意看最后一个参数
    public static PayResult createUnionPayResult(Date payDate, Double totalValue, Double paymentValue) {
        return new PayResult(new BankChannel(), payDate, totalValue, paymentValue, 0.0d, 0.0d,new UnionPayIntegralStrategy());
    }

    //微信支付 注意看最后一个参数
    public static PayResult createWxPayResult(Date payDate, Double totalValue, Double paymentValue, Double couponValue) {
        return new PayResult(new WxChannel(), payDate, totalValue, paymentValue, couponValue, 0.0d,new WxPayIntegralStrategy());
    }

    //支付宝支付 注意看最后一个参数
    public static PayResult createAliPayResult(PayChannel payChannel, Date payDate, Double totalValue, Double paymentValue, Double couponValue, Double loanValue) {
        return new PayResult(new AliPayChannel(), payDate, totalValue, paymentValue, couponValue, 0.0d,new AliPayIntegralStrategy());
    }

    //注意看最后一个参数
    private PayResult(PayChannel payChannel, Date payDate, Double totalValue, Double paymentValue, Double couponValue, Double loanValue, IntegralStrategy integralStrategy) {
        this.payChannel = payChannel;
        this.payDate = payDate;
        this.totalValue = totalValue;
        this.paymentValue = paymentValue;
        this.couponValue = couponValue;
        this.loanValue = loanValue;
        this.integralStrategy = integralStrategy;
    }

この時点で、積分システム全体が完全に再構築されました。

文末

記事に関する洞察や技術的な質問がある場合は、コメント領域にメッセージを残して話し合うことができ、間違いなく返信します。
誰もが私のBステーションに来て、私と遊ぶことを歓迎します。さまざまなAndroidアーキテクト、Ren Junbai売春婦の高度な技術的問題のビデオ説明〜
電車でのBステーション:https//space.bilibili.com/484587989

記事が好きな友達は、フォローすることを忘れないでください、去る前に好きなものを残してください〜

おすすめ

転載: blog.csdn.net/Androiddddd/article/details/109205440