[クリアコード]6章オブジェクトとデータ構造


clean_code


毎週火曜日、金曜日に勉強します.
火曜日の金曜日までに、一人二枚ずつ読んで、一人一枚ずつ発表します.
成分別に動的に調整

  • 火曜日:奇数の陣形、偶数の時間

  • 金曜:時准奇数場、陣形偶数場
  • テナント


    変数をプライベートと宣言する理由は、変数に依存したくないからです.
    しかし、ゲイトとセイトを公開し、変数を外部に暴露するのは当然だ.なぜだろうか.
  • 私もずっとゲイトセイトを無紙性として使っていましたが、セイトは私の必要な場所しか使いませんでした.ただし、変数を変更して取得し、外部から書き込む必要があります.publicと宣言すべきではないでしょうか.考えがある.
  • データ抽象

    public class Point{
    	public double x;
        public double y;
    }
    上記レベルは実施を外に暴露する.直交座標系を使用し、座標値を個別に設定する必要があります.変数をプライベートとして宣言しても、テナントを使用して実装できます.変数間に関数と呼ばれるレイヤが含まれていても、インプリメンテーションは非表示になりません.
    public interface Point{
    	double getX();
        double getY();
        void setCartesian(double x, double y);
        double getR();
        double getTheta();
        void setPolar(double r, double theta);
    }
    上のインタフェースは直交座標系か極座標系か分かりません.メソッドは、ポリシーに強制的にアクセスし、座標を読み込むときに単独で読み取る必要があり、設定するときに2つの値を同時に設定する必要があります.
  • 「ゲストサーバを使用して変数を処理するだけではクラスにはなりません.」
  • 抽象インタフェース(抽象化)により,ユーザは実現を知らずに資料のコアを操作できる.
    public interface Vehicle{
    	double getFuelTankCapacityInGallons();
        double getGallonsOfGasoline();
    }
    上のコードは具体的な数値で自動車の燃料状態を教えます.また,この2つの方法はいずれも変数値を読み取ることによって返されることはほぼ確実である.
    しかし、次のコードはパーセンテージ形式で自動車の燃料状態を教えるので抽象的です.そして、情報がどこから来るのか全く分かりません.
    public interface Vehicle{
    	double getPercentFuelRemaining();
    }
  • 「最善の方法は、ゲスト/ゲスト関数を何の考えもなく追加することです.」
  • 資料/オブジェクト非対称


    オブジェクトは抽象的に資料を隠し、関数のみを公開します.資料構造は直接資料を公開し、特別な関数を提供しない.
    public class Square{
    	public Point topLeft;
        public double side;
    }
    public class Rectangle{
    	public Point topLeft;
        public double height;
        public double width;
    }
    public class Geometry{
    	public final double PI = 3.141592;
        public double area(Object shape) throws NoSuchShapeException{
        	if (shape instanceof Square){
            	Square s = (Square)shape;
                return s.side * s.side;
            }else if (shape instanceof Rectangle){
            	Rectangle r = (Rectangle)shape;
                return r.height * r.width;
            }
            throw new NoSuchShapeException();
        }
    }
    以上のコードはclassを使用しますが、オブジェクト向けのコードではなく、プロセス向けのコードです.classを書くのになぜプログラムガイドのコードを書くのか、悪いコードだと思います.しかし、この本の著者は全く異なる観点を提出した.Geometryクラスに周長を求める周長()関数を追加するには、関数を1つ追加するだけです.ただし、新しいグラフィックを追加する場合は、Geometryクラスのすべての関数を変更する必要があります.次のオブジェクト向けコードは正反対です.persient()関数を追加する必要がある場合は、すべてのグラフィッククラスを変更する必要があります.ただし、新しいグラフィックを追加する場合は、既存の関数を変更する必要はありません.
    public class Square implements Shape{
    	private Point topLeft;
        private double side;
        
        public double area(){
        	return side*side;
        }
    }
    public class Rectangle implements Shape{
    	private Point topLeft;
        private double height;
        private double width;
        
        public double area(){
        	return height * width;
        }
    }
    以下に要約する.
  • プロセス向けのコードは関数を追加しやすいが、データ構造を追加するのは難しい.
  • オブジェクト向けのコードは、新しいオブジェクトを追加しやすいが、関数を追加するのは難しい.
  • 「簡単な資料構造やプログラムコードを使用するのに最適な場合があります.」
  • ディミットの法則


    モジュールは自分が操作したオブジェクトの詳細を知らないはずです.
    クラスCのメソッドfは、以下のオブジェクトのメソッドのみを呼び出すことができます.
  • 類C
  • fによって作成するオブジェクト
  • f買収対象
  • Cインスタンス変数に格納オブジェクト
  • 列車が衝突する

    final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();
    上記のコードは複数の車両で1列に接続された列車のように見えるので、粗い方式とされており、使用は避けたほうがよい.
    Options opts = ctxt.getOptions()
    File scratchDir = opts.getScratchDir();
    final String outputDir = scratchDir.getAbsolutePath();
    getter法によって分かるように、
  • ctxtオブジェクトはOptionを含み、optsはScratchDirを含み、ScratchDirはAbsolutePathを含む.1つの関数について知っている知識はたくさんあります.
    この部分はあまり理解できないので、死刑囚開発者の文章を参考にして、私も理解しました.
  • @Getter
    public class User { 
    	private String email; 
        private String name; 
        private Address address; 
    }
    
    @Getter
    public class Address { 
    	private String region;
        private String details;
    }
    上記のコードがある場合に次のサービス関数を使用すると、公則に反するコードとなります.オブジェクトに情報を送信するのではなく、オブジェクトの資料を表示しているからです.このサービストピックから,ユーザにはAddressが含まれ,AddressにはRegionが含まれていることがわかる.抽象化も実現しなかった.以下に修正します.
    @Service
    public class NotificationService { 
    	public void sendMessageForSeoulUser(final User user) {
        	if("서울".equals(user.getAddress().getRegion())) {
            	sendNotification(user);
    	    }
        }
    }
    次のコードはまずGetterメソッドを消しました.ソウルユーザーであることを確認する方法を追加し、Addressはソウル地域であることを確認する方法を追加した.サービスはisSeoulUser()メソッドを呼び出すだけで、オブジェクトの内部がどのように構成されているかはわかりません.
    public class Address { 
    	private String region;
        private String details;
        public boolean isSeoulRegion() { 
        	return "서울".equals(region); 
        } 
    }
    public class User { 
    	private String email; 
        private String name; 
        private Address address; 
        public boolean isSeoulUser() { 
    	    return address.isSeoulRegion();
        }
    }

    ヘテロ構造


    半分は客体,半分は資料構造の状態を雑種構造と呼ぶ.ヘテロ構造
    新しい関数の新しい資料構造を追加するのは難しいので,雑種構造を避ける.

    データ転送オブジェクト


    資料構造体の典型的な形式は,公開変数のみで関数のないクラスである.
    このようなデータ構造は、データ伝達オブジェクト(DTO)と呼ばれることがある.
    より一般的な形式はbean構造である.beanは、公開されたゲスト/ゲストを使用して非公開変数を操作する.
  • 「一種の偽カプセル化であり、一部の**純粋主義者または満足者の利益のみを満たす......?」
  • アクティビティレコード


    アクティビティレコードはDTOの特殊な形式です.saveやfindなどのナビゲーション関数も提供されます.アクティビティレコードにビジネスロジックメソッドをオブジェクトとして追加する開発者は、一般的な雑種構造です.
    答えは,アクティビティレコードはデータ構造であり,オブジェクトは単独で生成される.

    n/a.結論

  • オブジェクトは動作を公開し、資料を隠す.
  • オブジェクトは新しいオブジェクトタイプを追加しやすいが、新しいアクションを追加するのは難しい.
  • 資料構造表示資料.
  • の資料構造に動作を追加するのは簡単ですが、関数に資料構造を追加するのは難しいです.
  • 偏見はなく、現状に合った解決策を見つけなければなりません!!
  • リファレンスサイト


    死刑囚開発者