본문 바로가기
memo

[clean_code] 06장.객체와 자료구조

by 바까 2022. 7. 5.
반응형

⚠ 개인적으로 공부하려고 메모해둔거여서 정리가 안돼있고 깔끔하지않음


01. 자료추상화

6-1
//구현 외부노출

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



6-2
//구현 숨김

public interface Point {
    double getX();
    double getY();

    void setCartesian(double x, double y);
    
    double getR();
    double getTheta();

    void setPolar(double r, double theta);
}



//6-3
//자동차 연료 상태를 구체적인 숫자 값으로 알려줌
//두 함수가 변수값을 읽어 반환할 뿐이라는 사실이 확실

public interface Vehicle {
    double getFuelTankCapacityInGallons();
    double getGallonsOfGasoline();
}


//6-4
//자동차 연료 상태를 백분율이라는 추상적인 개념으로 알려줌
//정보가 어디서 오는지 전혀 드러나지않음

public interface Vehicle {
    double getPercentFuelRemaining();
}



/*
 * 자료를 세세하게 공개하기보다는 추상적인 개념으로 표현하는 것이 더 좋음
 * 인터페이스나 조회(get)/설정(set) 함수만으로는 추상화가 이루어지지 않음
 * 객체가 포함하는 자료를 표현할 가장 좋은 방법을 심각하게 고민해야함
 * 아무 생각 없이 조회(get)/설정(set) 함수를 추가하는 방법이 가장 나쁨


   //왜 자료값도....그렇게 추상적이어야하는지?
   이해가 잘안감
 */

02. 자료/객체 비대칭

//6-5 절차적인 도형

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();
    }
}



//6-6 다형적인 도형(객체지향적)

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
    }
}




/*

자료구조를 사용하는 절차적인 코드는 기존 자료구조를 변경하지 않으면서 새 함수를 추가하기 쉽다.
반면, 객체지향 코드는 기존 함수를 변경하지 않으면서 새 클래스를 추가하기 어렵다.

이는

절차적인 코드는 새로운 자료 구조를 추가하기 어렵다. 그러려면 모든 함수를 고쳐야한다.
객체 지향 코드는 새로운 함수를 추가하기 어렵다. 그러려면 모든 클래스를 고쳐야한다.

*/

/*

결론

복잡한 시스템을 짜다보면 새로운 함수가 아니라 새로운 자료타입이 필요한 경우가 생긴다. 
이때는 클래스와 객체 지향 기법이 가장 적합.

반면 새로운 자료타입이 아니라 새로운 함수가 필요한 경우도 생긴다.
이때는 절차적인 코드와 자료구조가 좀 더 접합

*/

03. 디미터법칙

디미터 법칙 : 잘 알려진 휴리스틱으로 모듈은 자신이 조작하는 객체의 속사정을 몰라야 한다는 법칙.

// ex 
// 클래스 C 의 메서드 f는 다음과 같은 메서드만 호출해야한다.
// - 클래스 C
// - f 가 생성한 객체
// - f 인수로 넘어온 객체
// - C 인스턴스 변수에 저장된 객체


1) 기차 충돌

// 잘못된 예시
// getOptions() 함수가 반환하는 객체의 getScratchDir() 함수를 호출한 후 getScratchDir() 함수가 반환하는 객체의 getAbsolutePath() 함수를 호출하는 구조

final String outputDir =  ctxt.getOptions().getScratchDir().getAbsolutePath();


// 위 코드는 다음과 같이 나누는 편이 좋다.

Options otps = ctxt.getOptions();
File scratchDir = opts.getScratchDir();
final String outputDir = scratchDir.getAbsolutePath();


// 만일 객체라면 내부구조를 숨겨야 하므로 위의 코드도 디미터 법칙을 위반한다.
// 반면 자료구조라면 당연히 내부 구조를 노출하므로 디미터 법칙이 적용되지 않는다.
// 자료구조라면 조회함수를 사용하지않고 다음과 같이 짜야한다.

final String outputDir = ctxt.options.scratchDir.getAbsolutePath;


2) 잡종구조
// 위와 같은 혼란으로 말미암아 절반은 객체, 절반은 자료구조인 잡종 구조가 나온다.
// 잡종구조는 새로운 함수는 물론이고 새로운 자료 구조도 추가하기 어렵다.

3) 구조체 감추기
// 만약 ctxt, optoins, scratchDir 가 객체라면 앞서 코드 예제처럼 줄줄이 사탕으로 엮어서는 안된다.

ctxt.getAbsolutePathOfScratchDirectoryOption(); -> ctxt  객체에 공개해야 하는 메서드가 너무 많아진다.
ctxt.getScratchDirectoryOption().getAbsolutePath(); -> getScratchDirectoryOption()이 객체가 아니라 자료 구조를 반환한다고 가정하므로 이것두 별로랜다.

// ctxt 객체에 임시파일을 생성할 때
BufferedOutputStrean bos = ctxt.createScratchFileStream(classFileName); -> ctxt는 내부 구조를 드러내지 않으며 모듈에서 해당 함수는 자신이 몰라야 하는 여러 객체를 탐색할 필요가 없다.!

04.자료전달객체


자료 구조체의 전형적인 형태는 공개변수만 있고 함수가 없는 클래스 -> 자료전달객체(DTO) 라고 부르기도함
//좀더 일반적인 형태로는 bean 구조이다. 
//빈은 private 변수는 get/set 함수로 조작한다.

//6-7 address.java

public calss Address {
    private String street;
    private String streetExtra;
    private String city;
    private String state;
    private String zip;

    public Address(String street, String streetExtra, String city, String state, String zip){

        this.street = street;
        this.streetExtra = streetExtra;
        this.city = city;
        this.state = state;
        this.zip = zip;
    }

    public String getStreet() {
        return street;
    }

    public String getSteetExtra() {
        return streetExtra;
    }

    public String getCity() {
        return city;
    }

    public String getState() {
        return state;
    }

    public String getZip() {
        return zip;
    }
}

객체는 여전히 어렵다..

Copyright 2022. GA-YOUN. All rights reserved

반응형

'memo' 카테고리의 다른 글

[clean_code] 08장.경계  (0) 2022.07.15
[clean_code] 07장.오류처리  (0) 2022.07.05
sql 문제 모음  (0) 2022.05.11
[엑셀]주간 업무일지 파일 공유  (0) 2021.10.01
Visual Studio Code 설치하기(한국어 변경)  (0) 2020.03.12

댓글