Search

리팩터링 2판 스터디 - 10

리팩터링 2판을 회사 팀 내 스터디로써 진행한다. 스터디에선 따로 책 내용을 정리를 하지 않고 주마다 정해진 분량까지 읽고 감상을 나눈다. 여기선 개인적으로 매 분량에 대한 정리와 짧은 감상을 올린다.

7.5. 클래스 추출하기

클래스는 명확하게 추상화하고 소수의 주어진 역할만 해야 한다.
분리의 신호:
메서드와 데이터가 너무 많다
따로 묶을 수 있다
함께 변경되거나 의존한다
제거해도 논리적으로 문제 없다
새 클래스로 옮길 때:
필드부터 옮긴다.
저수준 메서드(= 호출 당하는 일이 많은 메서드)부터 옮긴다.
다 옮기고 외부 노출 여부를 정한다.
값 객체
irb(main):001* class Point irb(main):002* attr_accessor :x, :y irb(main):003* irb(main):004* def initialize(x, y) irb(main):005* @x = x irb(main):006* @y = y irb(main):007* end irb(main):008* irb(main):009* def ==(other) irb(main):010* return false unless other.is_a?(Point) irb(main):011* @x == other.x && @y == other.y irb(main):012* end irb(main):013* irb(main):014> end => :== irb(main):016> p1 = Point.new(2, 3) => #<Point:0x000000012d9ff898 @x=2, @y=3> irb(main):017> p2 = Point.new(2, 3) => #<Point:0x000000012daf4de8 @x=2, @y=3> irb(main):018> p1 == p2 => true => [#<Point:0x000000012d9ff898 @x=2, @y=3>] irb(main):021> [p1].include?(p2) => true
Ruby
복사
irb(main):001* class Point irb(main):002* attr_accessor :x, :y irb(main):003* irb(main):004* def initialize(x, y) irb(main):005* @x = x irb(main):006* @y = y irb(main):007* end irb(main):008* irb(main):009* def ==(other) irb(main):010* return false unless other.is_a?(Point) irb(main):011* @x == other.x && @y == other.y irb(main):012* end irb(main):013* irb(main):014> end => :== irb(main):016> p1 = Point.new(2, 3) => #<Point:0x000000012d9ff898 @x=2, @y=3> irb(main):017> p2 = Point.new(2, 3) => #<Point:0x000000012daf4de8 @x=2, @y=3> irb(main):018> p1 == p2 => true => [#<Point:0x000000012d9ff898 @x=2, @y=3>] irb(main):021> [p1].include?(p2) => true
Ruby
복사

7.6 클래스 인라인하기

더 이상 제 역할을 못하는 클래스에게 적용한다.
= 클래스에 남은 역할이 (거의) 없을 때
지금과 다르게 나누기 위해서 우선 하나로 합친 후 나눈다.

7.7 위임 숨기기

숨기기, 즉 캡슐화는 모듈화의 핵심.
위임 메서드로 위임 객체의 존재를 숨긴다.

7.8 중개자 제거하기

단순히 전달만 하는 위임 메서드들이 귀찮아진다.
데메테르의 법칙이 아닌, “이따금 유용한 데메테르의 제안”이라고 하자.

7.9 알고리즘 교체하기

???

느낀점

핵심은 7.7에서 위임 “메서드”를 만드는 일 같다. 리팩터링 카탈로그의 나열 순서가 대구를 이루기도 하면서 연관성이 있다. 다른 유형으로도 서로 묶을 수 있고, 굉장히 일반화 시키면 “코드를 코드답게 쓰자”에 대한 이야기이다.
메서드(코드)로 되어 있다면 ‘맘대로’ 할 수 있다는 강력함을 느낀 소소한 사례
레코드, 컬렉션 캡슐화에서 이야기 하는 데이터가 아닌 코드로 다루기의 다른 버전이라고 느껴진다. 다만 클래스 자체에 집중?하니 설계와 맞닿아 있다는 느낌이 든다(7.6의 배경의 동기를 “논리적으로 문제가 없다면”이라고 표현한 것에서)
초반 1~3 장에서 이유에 대한 빌드업을 잘 한 것이 느껴진다. 배경 설명이 들었던 이야기이고 납득이 간다.
link iconmartinfowler.combliki: Value Object를 보니 값이 불변인 함수형 프로그래밍이 궁금해진다.
Small objects, such as points, monies, or ranges, are good examples of value objects. But larger structures can often be programmed as value objects if they don't have any conceptual identity or don't need share references around a program. This is a more natural fit with functional languages that default to immutability. 7
자동 리팩터링 무슨 말인가 manager() 지우지 말자는 것??
데메테르의 제안:
여전히 린트, 포매팅에 의존한 리팩터링은 유용하다고 생각한다.