CleanCode 6章オブジェクトとデータ構造

16580 ワード

変数をプライベート(private)として定義する理由は、次のとおりです.
変数に頼らないようにしたいから!
->変数のタイプや実装を自由に変えてもらいたい
なぜ変数をprivateとして宣言し、get、set関数をpublicに設定するのですか?

1.  データ抽象


// 1
public class Point {
    public double x;
    public double y;
}

// 2
public interface Point {
    double getX();
    double getY();
    void setCartesian(double x, double y);
    double getR();
    double getTheta();
    void setPolar(double r, duble theta);
}
2番を見ると資料の構造がはっきりしていて、体現していることがわかります.
変数間に関数を挿入しても、インプリメンテーションは非表示になりません.体現を隠すには抽象化が必要だ.
抽象的なインタフェースを提供し、ユーザーが実現を知らずに資料の核心を操作できるようにするのが本当のクラスです.
// 3
public interface Vehicle {
    double getFuelTankCapacityInGallons();
    double getGallonsOfGasoline();
}

// 4
public interface Vehicle {
    double getPercentFuelRemaining();
}
3号は具体的な数字で自動車の燃料状態を伝えた.
しかし4日は自動車の燃料状態をパーセンテージとした抽象概念を伝えた.
->3番変数値を読み込んで戻りますが、4番がどこから来るのか分かりません!
->資料を細かく表現するより抽象的な概念で表現した方がよい.
->アイデアのないget/set関数を追加するのは最悪です

2.  資料/オブジェクト非対称

  • オブジェクト(オブジェクト):データは抽象的に非表示であり、データを処理する関数
  • のみを公開する.
  • 資料構造:資料をそのまま公開する;
  • 関数は提供されていない
    
    // 절차적인 (자료구조)
    public class Square { 
    	public Point topLeft; 
    	public double side;
    }
    
    public class Rectangle { 
    	public Point topLeft; 
    	public double height; 
    	public double width;
    }
    
    public class Circle { 
    	public Point center; 
    	public double radius;
    }
    
    public class Geometry {
    	public final double PI = 3.141592653589793;
    
    	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;
    		} else if (shape instanceof Circle) {
    			Circle c = (Circle)shape;
    			return PI * c.radius * c.radius; 
    		}
    		throw new NoSuchShapeException(); 
    	}
    }
    
    // 다형적인 (Object)
    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;
    	} 
    }
    
    public class Circle implements Shape { 
    	private Point center;
    	private double radius;
    	public final double PI = 3.141592653589793;
    
    	public double area() {
    		return PI * radius * radius;
    	} 
    }

  • プロセス構造に関数を追加しても影響はありません.ただし、新しいグラフィックを追加するには、すべての関数を変更する必要があります.

  • マルチシェイプ構造に新しいグラフィックを追加しても影響はありません.ただし、新しい関数を追加する場合は、すべてのグラフィッククラスを変更する必要があります.
  • ->相補的な特徴を持つ.
    プログラムコードは、既存のデータ構造を変更せずに新しい関数を追加しやすい.
    しかし、新しい資料構造を追加するのは難しい.

    ->新しいデータ型ではなく、新しい関数が必要な場合に有利です。


    オブジェクト向けのコードは、既存の関数を変更せずに新しいクラスを追加しやすい.
    新しい関数を追加するのは難しいです

    ->新しい関数ではなく、新しいデータ型が必要な場合に有利です。


    3. ディミットの法則


    ディミットの法則は空想で、モジュールは自分が操作する対象の詳細を知らないはずだ.
    △ヒューリー主義とは、経験に基づいて問題を解決したり、学習したり、発見したりする方法を指す.最良の年ではなく知識レベルの方法を指す.
    例えば、Class Cの方法f
  • Class C
  • fによって作成するオブジェクト
  • f買収対象
  • Cインスタンス変数に格納オブジェクト
  • 呼ぶしかない.
    見知らぬ人を警戒して、友達と遊ぶだけだ.
  • 列車衝突
  • final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();
    複数の車両が列車のように見えるため、列車衝突と呼ばれています.
    下図のように書きやすい.
    Options opts = ctxt.getOptions();
    File scratchDir = opts.getScratchDir();
    final String outputDir = scratchDir.getAbsolutePath();
    上記の例では、ctxt、Options、およびScratchDirがオブジェクトである場合、メトリック・ルールに違反することを示しています.資料構造の場合、以下の変更により遵守コードとなります.
    final String outputDir = ctxt.options.scratchDir.absolutePath

    4.雑種構造


    簡単な資料構造でもget/set関数のフレームワーク基準を設定するため、半分がオブジェクトで、半分が資料構造の雑種構造になります.
  • 重要な機能を実行する関数と共通変数は
  • である.
  • public get/set関数プライベート変数
  • を直接暴露
    両サイドの構造の欠点だけが集中した構造なので避けましょう.
    (プログラマは関数やタイプを保護するか公開するか分からないため、設計が不適切です)

    5.構造体を隠す


    ctxt、options、scratchDirがオブジェクトの場合は、オブジェクトの内部を非表示にする必要があります.
    BufferedOutputStream bos = ctxt.createScratchFileStream(classFileName);
    取り替えるときれいになります.