lombookはピットと思考を踏みます.

4607 ワード

ロムックに接触するのは長い時間がありますが、コードを減らすためにロムックをたくさん使います.それとも新しいチームでコードを作成して古いコードを維持します.
個人的にはlombookを使うことを主張していません.それがもたらした価格はその便利さを相殺するのに十分です.しかし、チームコードのスタイルは一致しているので、やはり使い続けるべきです.使用中に問題がありました.研究と思考をして記録してください.
1.雑多な問題
これらは最初に私がロックが嫌いだった理由です.
1.1追加的な環境構成
IDEプラグイン+jarパッケージとしては、IDEの一連の構成が必要です.現在はideaでの配置は簡単ですが、数年前にeclipseでも配置されていますので、複雑になります.
1.2伝染性
一般的に言えば、対外タクシーのjarカバンはできるだけ三者のカバン依存を減らす方がいいです.そうすると、コンパイルのスピードを速くしてもいいし、バージョンの衝突を減らすことができます.一旦resourceのカバンにlombookを使ったら、他の人がソースを見たいならプラグインを入れなければなりません.
このような対外的なjarのカバンの中でlombookを使わないのは約束だけです.ある日、lombookが初めてこのjarのカバンに導入された時、新しい感染者は避けられません.
1.3コード可読性を低減する
位置決め方法の呼び出し時に、自動的に発生するコードについては、ゲッター/setterはまだ良いと思います.メンバー変数を見つけたら、find usageは、コンテキストによってどのような種類か区別します.equals()このように、探したいならテストコードを書いてからfind usageに行くしかないです.
現在主流のideは基本的にgetter/setterコードの自動生成をサポートしています.lombookの注釈と比べて、一回入力するかそれとも一回のショートカットの違いで、実際に軽減される作業量は非常に小さいです.
2.@Equals AndHashCodeとequals()
2.1原理
この注釈設定callSuper=trueの場合、親クラスのequlas()方法が起動され、コンパイル後のクラスのファイルコードのセグメントは以下の通りである.
public boolean equals(Object o) {
    if (o == this) {
        return true;
    } else if (!(o instanceof BaseVO)) {
        return false;
    } else {
        BaseVO other = (BaseVO)o;
        if (!other.canEqual(this)) {
            return false;
        } else if (!super.equals(o)) {
            return false;
        } else { 
            //       
        }
    }
}
つのクラスの親がObject(javaではデフォルトでは相続関係のないクラスの親がObject)である場合、ここでObjectのequals()を呼び出します.
public boolean equals(Object obj) {
    return (this == obj);
}
2.2問題
親クラスがObjectであり、@EqualsAndHashCode(callSuper = true)に注釈されたクラスを使用する場合、このクラスはlombokによって生成されたequals()方法は、2つのオブジェクトが同一のオブジェクトである場合に限って、trueに戻ります.この行為はほとんどの時間が予期に合わず、equals()はその意味を失った.equals()がこのように動作することを期待しても、残りの属性比較コードは邪魔になり、コードの分岐カバー率が大幅に低下します.6000行近くのコードのサービスシステムを例に挙げて、この問題を修復し、対応するテストケースを作成することで、全体のJAcoco分岐のカバー率を10%~15%向上させることができます.
反対に、この注釈はJAcocoの下では1行のコードしかカウントされないので、カバーされていない行数は多くないはずです.
2.3解決
いくつかの解決方法が参考になります.
  • はこの注釈を使用しない.ほとんどのpojoは私達はequalsを呼んで比較しません.実際に使ったら書き直してもいいです.
  • callSuper = trueを削除する.父類がObjectなら、おすすめです.
  • は、親類のequals()方法を書き換え、親類が同じように実現されたOjbectのequals()を起動または使用しないことを保証する.
  • 2.4その他@data注釈は、親タイプのequals()を起動しないため、Object.equals()のピットを回避する@EqualsAndHashCode注釈を含むが、他のピットをもたらすことがある.詳細は@data を参照してください.
    3.@data
    3.1穴から出て他の大きな穴に落ちます.
    上記で@Equals AndHashCode(calSuper=true)注釈の坑に言及しましたが、@dataは避けることができますか?不幸なことに、ここにも穴があります.@dataは実際に使用されている@EqualsAndHashCodeですので、親類のequals()を呼び出していません.私たちは親タイプの属性を比較する必要がある場合、比較できません.例は以下の通りです
    
    @Data
    public class ABO {
        private int a;
    
    }
    
    @Data
    public class BBO extends ABO {
    
        private int b;
    
        public static void main(String[] args) {
    
            BBO bbo1 = new BBO();
            BBO bbo2 = new BBO();
    
            bbo1.setA(1);
            bbo2.setA(2);
    
            bbo1.setB(1);
            bbo2.setB(1);
    
            System.out.print(bbo1.equals(bbo2)); // true
        }
    }
    明らかに、二つのサブクラスは親の属性比較を無視している.これは親類の属性が子類に対して見えないからではないです.父類prvate属性をprotectedに変更しても、結果は同じです.
    3.2解決方法
  • @dataを使って、継承関係がないようにします.kotlinのようなやり方で、具体的には次のセクション
  • を参照してください.
  • 自己でequals()を書き換えます.lombokは明示的書き換え方法を生成しません.
  • は、明示的に@EqualsAndHashCode(callSuper = true)を使用する.lombookは明示的に指定されます.
  • 3.3@dataとdataについて@dataの行動を知ると、それはコツリント言語のダタ修饰符と似ています.いずれも自動的にいくつかの方法を生成し、継承にも問題があります.前者は継承関係があると踏んでしまいますが、後者の修飾の種類はfinalであり、引き継ぐことができません.kotlinさんはなぜこのようにしましたか?二人は何か連絡がありますか?広く伝えられた文章(Javaを捨ててKotlinに変えた6ヶ月後、後悔しました.)では、data修饰符について、次のように述べています.
    Kotlinはequals()、hashCode()、toString()およびcopy()に対してとても良い実現があります.簡単なDDOを実現する際には非常に有用である.しかし、データには深刻な制限があることを覚えてください.データクラスを拡張できない、または抽象化できないので、コアモデルではそれらを使用しないかもしれません.
    この制限はKtlinの間違いではない.equals()がLiskyov原則に違反していない場合は、正しい値に基づくデータは生成できない.
    Liskyovの原則については、簡単に要約できます.
    一つのオブジェクトは、その出現のどこでも、サブクラスのインスタンスで置き換えられ、プログラムのエラーを引き起こすことはありません.言い換えれば、サブクラスが任意の場所でベースクラスを置換し、ソフトウェア機能が影響を受けない場合、このような継承関係のモデリングは合理的である.
    前の章の議論によると、equals()の実現は実際にビジネスシーンの影響を受けており、親の属性を比較するかどうかにかかわらず可能である.しかし、kotlinはequals()のデフォルトの行為を決定できず、親属性を使用しないとこの原則に違反し、親属性を使用してObject.equals()を呼び出した罠に落ちる可能性があります.
    この問題を回避したのは、コートリンの開発者です.父の属性を使わず、相続を禁止すればいいです.kotlinの利用者だけが、自分が定義したdataオブジェクトが引き継げないことに気づき、このキーワードを削除して手書きで対応する方法を書かざるを得ません.
    振り返ってみると、@dataはこれらのピットを避けていません.より多くの選択権を開発者に任せているだけで、もう一つの方法です.
    4.後記
    他のlombookの注釈は実際の使用量が少ないです.全体的に公式文書を読みましたが、他の問題はまだ発見されていません.実際には公式文書でもequalsのピットに言及しています.