コアコードのクリーンアップ(6章オブジェクトとデータ構造)
データ構造vsオブジェクト
例Verhicle
データ構造
// 자료 구조
public interface Vehicle {
double getFuelTankCapacityInGallons(); // 연료탱크 용량(갤런 단위)
double getGallonsOfGasoline(); // 가솔린 (갤런 단위)
}
public class Car implements Vehicle {
double fuelTankCapacitInGallons;
double gallonsOfGasoline;
public double getFuelTankCapacityInGallons() {
return this.fuelTankCapacitInGallons;
}
public double getFuelTankCapacityInGallons() {
return this.gallonsOfGasoline;
}
}
これは、ビジネスロジックが純粋なデータを格納していない資料構造の役割です.
オブジェクト
// 객체
public interface Vehicle {
double getPercentFuelRemain();
}
public class Car implements Vehicle {
private double fuelTankCapacitInGallons;
private double gallonsOfGasoline;
public Car(double fuelTankCapacitInGallons, double gallonsOfGasoline) {
if (fuelTankCapcitInGallons <= 0) {
throw new IllegalArgumentException("fuelTankCapacitInGallons must be greater than zero");
}
this.fuelTankCapacitInGallons = fuelTankCapacitInGallons;
this.gallonsOfGasoline = gallonsOfGasoline;
}
public double getPercentFuelRemain() {
return this.gallonsOfGasoline / this.fuelTankCapacitInGallons * 100;
}
}
上記のコードは、作成者にビジネスロジックに関連するコードを含み、フィールドをプライベート化して資料を非表示にします.
サンプルシェイプ
データ構造
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) {
Shape 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();
}
}
Triangleという新しいクラス(データ構造)が追加されたら?if-else文はarea()関数で変更する必要があります.
// 자료 구조
public interface Vehicle {
double getFuelTankCapacityInGallons(); // 연료탱크 용량(갤런 단위)
double getGallonsOfGasoline(); // 가솔린 (갤런 단위)
}
public class Car implements Vehicle {
double fuelTankCapacitInGallons;
double gallonsOfGasoline;
public double getFuelTankCapacityInGallons() {
return this.fuelTankCapacitInGallons;
}
public double getFuelTankCapacityInGallons() {
return this.gallonsOfGasoline;
}
}
// 객체
public interface Vehicle {
double getPercentFuelRemain();
}
public class Car implements Vehicle {
private double fuelTankCapacitInGallons;
private double gallonsOfGasoline;
public Car(double fuelTankCapacitInGallons, double gallonsOfGasoline) {
if (fuelTankCapcitInGallons <= 0) {
throw new IllegalArgumentException("fuelTankCapacitInGallons must be greater than zero");
}
this.fuelTankCapacitInGallons = fuelTankCapacitInGallons;
this.gallonsOfGasoline = gallonsOfGasoline;
}
public double getPercentFuelRemain() {
return this.gallonsOfGasoline / this.fuelTankCapacitInGallons * 100;
}
}
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) {
Shape 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();
}
}
オブジェクト
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;
}
}
Triangleというレベルを追加したら?Triangleクラスを作成したら、Shapeインタフェースを継承し、Area()関数を上書きします.
すなわち,オブジェクト向けのコードは新しいクラスを容易に追加できる.ただし、関数を追加する必要があります.
状況に合った選択をすればいい。
データ構造
オブジェクト
オブジェクト-メジャー・ルール
クラスCのメソッドfは、以下のオブジェクトのメソッドのみを呼び出すことができます。
A a = new A();
B b = a.getB() (O)
C c = a.getB().getC(); (X)
公制の法則に反する場合
// 객체 - 기차 충돌. 디미터의 법칙 위배
final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();
// 자료구조 - OK
final String outputDir = ctxt.options.scratchDir.absolutePath;
// 객체에 대한 해결책이 아니다. getter를 통했을 뿐, 값을 가져오는 것은 자료구조이다.
ctxt.getAbsolutePathOfScratchDirectoryOption();
ctxt.getScratchDirectoryOption().getAbsolutePath();
// 왜 절대 경로를 가져올까.. 근본 원인을 생각해보자!
// 객체는 자료를 숨기고 자료를 다루는 함수만 공개한다.
BufferedOutputStream bos = ctxt.createScratchFileStream(classFileName);
DTO
異なるレイヤ間でデータを交換するために使用
論理はありません.フィールドのみです.
通常クラス名はDto(またはDTO)で終わる.
getter/setterもあります.
- Beans
Java bean:データを表すJavaオブジェクト
メンバー変数はprivateプロパティです.
getterとsetterがあります.
public class AddressDto {
private String street;
private String zip;
}
public AddressDto(String street, String zip) {
this.street = street;
this.zip = zip;
}
public String getStreet() {
return street;
}
public String setStreet(String street) {
this.street = street;
}
public String getZip() {
return zip;
}
public String setZip(String zip) {
this.zip = zip;
}
Active Record
データベース行をオブジェクトにマッピングするモード
public class Employee enxtends ActiveRecord {
private String name;
private String address;
...
}
// ----
Employee bob = Employee.findByName("Bob Martin");
bob.setName("Robert C. Martin");
bob.save();
リファレンス
これらの情報はゼロベースラインクリーニングコード毎月1冊を聞いた後に整理された.
Reference
この問題について(コアコードのクリーンアップ(6章オブジェクトとデータ構造)), 我々は、より多くの情報をここで見つけました
https://velog.io/@coconenne/클린코드-핵심-정리-5장-객체와-자료구조
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
Reference
この問題について(コアコードのクリーンアップ(6章オブジェクトとデータ構造)), 我々は、より多くの情報をここで見つけました https://velog.io/@coconenne/클린코드-핵심-정리-5장-객체와-자료구조テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol