독서 노트 (4) 의 대상 과 데이터 구조

7390 단어
변 수 를 private 로 설정 한 이 유 는 다른 사람들 이 이 변수 에 의존 하고 싶 지 않 기 때 문 입 니 다.우 리 는 또 심혈 을 기울 일 때 그 유형 을 자 유 롭 게 수정 하거나 실현 하고 싶다.그런데 왜 그렇게 많은 프로그래머 들 이 대상 에 게 자동 으로 할당 기와 수치 추출 기 를 추가 하고 개인 변 수 를 대중 에 게 공개 해 야 합 니까? 마치 공공 변수 와 같 습 니 다.
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, double theta);
}

세 션 2 의 아름 다운 점 은 사각형 좌표계 에서 이 루어 질 지 극 좌표계 에서 이 루어 질 지 모른다 는 점 이다.둘 다 아 닐 수도 있어!그러나 이 인 터 페 이 스 는 데이터 구 조 를 분명하게 보 여 주 었 다.
그러나 이 는 데이터 구조 뿐만 아니 라 액세스 전략 도 고정 시 켰 다.어떤 좌 표를 단독으로 읽 을 수 있 지만, 원자 조작 을 통 해 모든 좌 표를 설정 해 야 한다.
한편, 세 션 1 은 직사각형 좌표계 에서 이 루어 지고 우리 에 게 어떤 좌 표를 조작 하 라 고 요구 하면 실현 이 드 러 났 다.실제로 변 수 는 모두 사유 이 고 우 리 는 변수 추출 기와 할당 기 를 통 해 변 수 를 사용 하 더 라 도 그 실현 은 여전히 드 러 났 다.
숨겨 진 실현 은 변수 사이 에 함수 층 을 올 리 는 것 만 간단 한 것 이 아 닙 니 다.숨 기 고 실현 하 는 것 은 추상 과 관련 이 있다!클래스 는 단순히 수치 추출 기와 값 부여 기로 그 변 수 를 외부 로 밀어 내 는 것 이 아니 라 추상 적 인 인 인 터 페 이 스 를 노출 시 켜 사용자 가 데이터 구조의 실현 을 이해 하지 않 아 도 데이터 본 체 를 조작 할 수 있 도록 한다.
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.width * r.height;
        } else if (shape instanceOf Circle) {
            Circle c = (Circle) shape;
            return PI * c.radius * c.radius;
        }
        
        throw new NoSuchShapeException();
    }
    
}


위의 코드 는 과정 을 향 한 코드 스타일 을 보 여 주 었 다.Geometry 류 는 세 가지 모양 류 를 조작 하 는데 모양 류 는 모두 간단 한 데이터 구조 로 어떠한 행위 도 하지 않 는 다.모든 행 위 는 Geometry 류 에 있다.
대상 프로그래머 들 은 프로 세 스 코드 라 고 비 웃 을 수도 있다. 그들 이 옳 은 것 같 지만 이런 비 웃 는 것 은 정확 하지 않다.Geometry 클래스 에 primeter () 함 수 를 추가 하면 어떻게 될 지 생각해 보 세 요.그러면 형상 류 는 이 로 인해 영향 을 받 지 않 는 다!다른 한편, 모양 류 를 추가 하면 Geometry 의 모든 함 수 를 수정 하여 처리 해 야 합 니 다.주의 하 세 요. 이 두 가지 상황 도 직접적 으로 대립 되 어 있 습 니 다.
다음은 대상 지향 방안 을 살 펴 보 자.여기 area () 방법 은 다 형 이 므 로 Geometry 류 가 필요 없습니다.따라서 새로운 모양 을 추가 하면 기 존의 함수 가 하나 도 영향 을 받 지 않 고 새로운 함 수 를 추가 할 때 모든 모양 을 수정 해 야 합 니 다.

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 width * height;
    }
}

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. 디 미트 법칙 (데 메 터 의 법칙)
디 미트 법칙 은 최소한 의 원칙 (Least Knowledge Principle, 약자 LKP) 이 라 고도 한다. 즉, 한 대상 이 다른 대상 에 대해 가능 한 한 적 게 알 고 낯 선 사람과 말 을 하지 않 아야 한 다 는 것 이다.
모듈 은 그것 이 조작 하 는 대상 의 내부 상황 을 이해 해 서 는 안 된다.위 절 에서 보 듯 이 대상 은 데 이 터 를 숨 기 고 노출 작업 을 합 니 다.이 는 대상 이 액세스 기 를 통 해 내부 구 조 를 노출 해 서 는 안 된다 는 뜻 으로 내부 구 조 를 숨 기지 않 고 노출 하 는 것 과 같 기 때문이다.
더 정확히 말 하면 디 미트 법칙 은 클래스 C 의 방법 f 은 대상 의 방법 만 사용 해 야 한다 고 주장 한다.
  • C
  • f 가 만 든 대상
  • 매개 변수 로 f 에 전달 하 는 대상
  • C 의 실체 변수 가 가 진 대상
  • 방법 은 어떤 함수 에서 돌아 오 는 대상 의 방법 을 호출 해 서 는 안 된다.다시 말 하면 친구 와 만 이야기 하고 낯 선 사람과 말 을 하지 않 는 다 는 것 이다.
    다음 코드 는 디 미트 법칙 을 위반 했다. getOptions() 반환 값 getScratchDir() 을 호출 하고 getScratchDir() 반환 값 getAbsolutePath() 방법 을 호출 했 기 때문이다.
    final String outputDir = ctx.getOptions().getScratchDir().getAbsolutePath();
    

    3.1 기차 사고
    이런 코드 는 흔히 기차 사고 라 고 불 린 다.가장 좋 은 것 은 다음 과 같이 나 누 는 것 이다.
    Options opts = ctx.getOptions();
    File scratchDir = opts.getScratchDir();
    final String outputDir = scratchDir.getAbsolutePath();
    

    상기 코드 는 ctx, Options, ScratchDir 가 대상 이 라면 내부 데이터 구 조 는 숨 기 고 노출 되 지 않 아야 하 며 디 미트 법칙 을 위반 합 니 다.만약 에 ctx, Options, ScratchDir 가 데이터 구조 일 뿐 아무런 행위 가 없다 면 그들 은 내부 구 조 를 자 연 스 럽 게 드 러 낼 것 이 고 디 미트 법칙 은 적용 되 지 않 을 것 이다.
    만약 에 데이터 구조 가 단순히 공공 변 수 를 가지 고 함수 가 없 으 며 대상 은 사유 변수 와 공공 함 수 를 가지 고 있다 면 이 문 제 는 그리 헷 갈 리 지 않 을 것 이다.
    3.2 혼합
    혼합 은 혼합 구조의 출현 을 초래 했 고 반 은 대상 이 며 반 은 데이터 구조 이다.어떤 취지 에서 든 공공 접근 기와 값 변경 기 는 개인 변 수 를 공개 화하 고 외부 함수 가 프로 세 스 프로그램 으로 데이터 구 조 를 사용 하도록 유도 합 니 다.
    이런 혼합 은 새로운 함 수 를 추가 하 는 난이 도 를 증가 시 켰 고 새로운 데이터 구 조 를 추가 하 는 난이도 도 증가 하 였 으 므 로 이런 구 조 를 창조 하 는 것 을 피해 야 한다.
    3.3 숨겨 진 구조
    만약 ctx, Options, ScratchDir 가 실제 행 위 를 가 진 대상 이 라면 우 리 는 어떻게 이것 을 개조 합 니까?
    임시 디 렉 터 리 의 절대 경 로 를 가 져 오 는 두 가지 방안:
    ctx.getAbsolutePathOfScratchDirectoryOption();
    
     
    
    ctx.getScratchDirectoryOption().getAbsolutePath();
    
    

    첫 번 째 방안 은 ctx 대상 에서 방법의 노출 을 초래 할 수 있다.두 번 째 방안 은 ggetScratchDirectory Option 이 대상 이 아 닌 데이터 구 조 를 되 돌려 준다 고 가정 하 는 것 이다.두 가지 방안 모두 느낌 이 좋 지 않다.
    만약 ctx 가 대상 이 라면 내부 상황 을 요구 하 는 것 이 아니 라 무엇 을 요구 해 야 한다.그런데 왜 우 리 는 임시 디 렉 터 리 의 절대 경 로 를 얻어 야 합 니까?예 를 들 어 소스 코드 는 실제 임시 디 렉 터 리 의 절대 경 로 를 가 져 와 이름 을 만 드 는 임시 파일 입 니 다.
    그래서 직접 ctx 대상 에 게 이 일 을 시 키 는 것 이 어 떻 습 니까?
    BufferedOutputStream bos = ctx.createScrathFileStream(classFileName);
    

    이렇게 ctx 는 내부 데이터 구 조 를 숨 기 고 현재 함수 가 알 지 말 아야 할 대상 을 탐색 해서 디 미트 법칙 을 위반 하 는 것 을 방지 합 니 다.
    4 데이터 전송 대상
    가장 세련 된 데이터 구 조 는 공공 변수 만 있 고 함수 가 없 는 클래스 입 니 다.이런 데이터 구 조 는 때때로 데이터 전송 대상 또는 DTO (Data Transfer Objects) 라 고 불 린 다.
    이런 구조 대상 은 데이터베이스 통신 이나 소켓 이 전달 하 는 메 시 지 를 분석 하 는 데 매우 유용 하 다.
    이런 구 조 는 흔히 'bean' 구조 로 봉 인 됩 니 다. 콩 구 조 는 할당 기와 수치 추출 기 가 작 동 하 는 개인 변 수 를 가지 고 있 습 니 다.이런 반 봉 투 는 일부 OO 순화 론 자 들 로 하여 금 좀 편안 함 을 느끼 게 하지만, 일반적으로 다른 좋 은 점 은 없다.
    5. 총화
    대상 노출 행위, 데이터 숨 기기.기 존 행 위 를 수정 하지 않 고 새로운 대상 유형 을 추가 하 는 데 편리 하 며 기 존 대상 에 새로운 행 위 를 추가 하기 도 어렵다.데이터 구조 가 데 이 터 를 노출 시 켜 뚜렷 한 행동 이 없다.기 존 데이터 구조 에 새로운 행 위 를 추가 하 는 동시에 기 존 함수 에 새로운 데 이 터 를 추가 하 는 구조 도 어렵다.
    우 리 는 수중 작업 의 성격 에 따라 사용 대상 을 유연 하 게 선택해 야 합 니까? 아니면 데이터 구 조 를 유연 하 게 선택해 야 합 니까?

    좋은 웹페이지 즐겨찾기