본 게시물은 조영호님의 저서 오브젝트를 학습하면서 정리한 내용입니다.

객체지향 개발자라면 꼭 알아야할 내용들이 가득한 책이기 때문에 참고만하시고 반드시 책을 구매해서 읽어보길 권해드려요!

(네이버 도서 구매링크 클릭)

저작물에 대한 문제가 발생할 경우 비공개 처리하겠습니다.


 

  • 객체지향 패러다임의 관점에서 핵심은 역할, 책임, 협력
  • 객체지향의 본질은 협력하는 객체들의 공동체를 창조하는 것
    • 협력을 구하기 위해 적절한 객체를 찾음 → 적절한 책임을 할당
  • 협력을 위한 역할과 책임을 고민하는 것이 중요

 

협력

  • 객체지향 원칙을 따르면 애플리케이션의 제어 흐름이 다양한 객체들에게 균형있게 분배됨
    • 어떤 하나의 객체에 의해 통제되지 않음
  • 객체들 사이에 메시지를 주고 받으면서 상호작용을 함 ( 협력 )
  • 자율적인 객체들의 공동체
  • 기능을 구현하는 유일한 방법
  • 메시지를 받은 객체는 메서드를 실행해서 응답
    • 메시지에 대한 처리방법은 수신한 객체가 스스로 선택(메서드)

 

자율적인 객체

  • 자신의 상태를 직접 관리하고 스스로 결정에 따라 행동하는 객체
  • 필요한 정보, 정보에 기반한 행동을 같은 객체 안에 모아야 함
  • 가장 기본적인 방법으로는 내부 구현을 캡슐화하는 것

 

협력이 설계를 위한 문맥을 결정한다

  • 객체가 협력에 참여하기위해 적절한 행동을 보유해야 함
  • 객체의 행동은 협력의 필요에 따라 결정되어야 함
    • 협력이 바뀌면 행동도 바뀌어야 함
  • 협력은 객체가 필요한 이유, 객체가 수행하는 행동의 동기를 제공
    • 왜 이 객체가 필요한가? → 협력하고 있기 때문이다.
    • 이 객체는 왜 이러한 행동을 하는가 → 협력에 참여하고 있기 때문이다.
  • 협력은 객체지향 설계에서의 문맥
  • 상태는 객체가 행동하는데 필요한 정보에 의해 결정

 

💡
객체들이 서로 상호작용하는 것, 이러한 메시지의 흐름을 협력이라고 부르는데 Context라는 모호해서 어려운 키워드를 명확하게 이해할 수 있는 부분이다.

 

책임

책임이란 무엇인가

  • 협력에 참여하기위해 객체가 수행하는 행동
  • 객체에 의해 정의되는 응집도 있는 행위의 집합
  • 객체의 정보와 행동으로 구성
    • 하는 것
      • 객체가 스스로 수행하는 것 ( 직접 계산 등..)
      • 다른 객체의 행동을 시작시키는 것
      • 다른 객체의 활동을 제어하고 조절하는 것
    • 아는 것
      • 사적인 정보 (private data)
      • 관계된 객체에 관해 아는 것 (합성)
      • 자신이 유도하거나 계산할 수 있는 것에 관해 아는 것
  • 협력 안에서 객체에게 할당한 책임외부의 인터페이스내부의 속성을 결정
  • 적절한 협력 → 적절한 책임을 제공, 적절한 책임을 객체에게 할당 → 유연한 설계 가능
  • 객체에게 얼마나 적절한 책임을 할당하느냐가 설계 품질을 결정함

 

책임과 메시지

  • 일반적으로 책임과 메시지의 크기는 다름
  • 책임은 객체가 수행할 수 있는 행동 ( 종합적, 간략하고 서술 )→ 메시지보다 추상적인 개념
  • 단순한 책임이 여러 개의 메시지로 분할 되기도 함
  • 하나의 객체가 수행할 수 있다고 생각했던 책임이 여러 객체들의 협력으로 만들어지기도 함

 

CRC 카드

  • 객체지향설계를 돕기위해 고안된 방법
  • 각각이 후보, 책임, 협력을 뜻 함
    • 후보
      • 카드 뒤에 후보의 목적을 기술
        • 후보가 외부에 제공해야 하는 서비스를 한 문장으로 기술
    • 책임
      • 카드 앞면에 선을 긋고 한쪽에 목적을 세분화해서 무엇을 알고 무엇을 해야하는가 기재
    • 협력
      • 책임을 수행하려면 협력할 협력자 나열
  • 설계를 하면서 직접 눈으로 보고 손으로 만질 수 있을때 효과적

 

책임할당

  • 자율적인 객체를 만드는 가장 기본적인 방법→ 책임을 수행하는데 필요한 정보를 가장 잘 아는 전문가에게 책임 할당
  • ⇒ 협력에 필요한 지식과 방법 잘 알고 있는 객체에게 도움을 요청
  • 책임을 할당하는 것만으로도 상태와 행동을 함께 가지는 자율적인 객체를 만들 가능성이 높아짐

 

책임할당의 순서

  • 협력이라는 문맥을 정의
    • 시스템이 제공하는 기능을 하나의 책임으로 바라보는 것부터 시작
  • 시스템 책임을 완료하는데 필요한 작은 책임을 찾아내고 객체에 할당하길 반복
    • 메시지의 이름을 결정하는 것으로 책임을 할당
      • 책임을 수행하는 유일한 방법은 메시지이기 때문
    • 메시지를 처리할 객체를 선택
      • 정보를 소유하고 있거나 정보의 소유자를 잘 아는 전문가를 찾는 것

⇒ 이렇게 결정된 메시지는 퍼블릭 인터페이스가 됨

 

책임 주도 설계

  • 책임을 찾고 수행할 객체를 찾아 할당하는 방식의 설계를 말함
  • 어떤 책임을 선택하느냐에 따라 전체적인 설계의 방향과 흐름이 결정됨
  • 객체의 구현이 아닌 책임에 집중할 수 있게 함
    • 유연하고 견고한 객체지향 시스템의 가장 중요한 재료
  • 책임을 할당할 때 가장 중요한 요소
    • 메시지가 객체를 결정
    • 행동이 상태를 결정

메시지가 객체를 결정한다

  • 책체가 메시지를 선택하는 것이 아님 → 메시지가 객체를 선택
  • 최소한의 인터페이스를 갖게 하기 위함
    • 필요한 메시지가 식별될 때까지 퍼블릭 인터페이스에 추가되는 것이 없음→ 꼭 필요한 크기의 인터페이스를 갖게 됨
  • 추상적인 인터페이스를 갖게 하기 위함

 

행동이 상태를 결정한다

  • 상태는 객체가 행동을 정상적으로 수행하기위해 필요한 재료일 뿐
  • 객체의 행동은 객체가 협력에 참여할 수 있는 유일한 방법
  • 객체의 상태에 초점을 맞추면 객체의 내부 구현이 객체의 퍼블릭 인터페이스에 노출됨→ 캡슐화 저해

 

💡
책임을 수행하는 방법은 메시지 뿐이다. 유일한 방법이기때문에 힌트는 여기에 있었다. 책임들의 흐름인 협력( 문맥 )을 완성하기 위해서는 결국 메시지를 정하고 메시지를 수행할 객체(역할)을 확정하면 되는 것이었다. 단순하게 머릿속의 흐름대로 개발을 하면 자연스럽게 상태와 구현을 그대로 노출하는 자율성을 잃어버린 객체를 만들게 될 것이다.

 

역할

역할과 협력

  • 역할 : 협력안에서 수행하는 책임의 집합
    • 다른 것으로 교체할 수 있는 책임의 집합
  • 협력을 모델링할 때 → 특정한 객체가 아니라 역할에게 책임을 할당한다고 생각해야 함
  • 책임을 할당한다는 것을 분해
    • 역할을 찾음
    • 역할을 수행하는 객체를 선택

유연하고 재사용 가능한 협력

  • 역할의 중요성 : 역할을 통해 유연하고 재사용 가능한 협력을 얻을 수 있음
  • 역할은 하나의 슬롯
  • 구체적인 객체를 포괄하는 추상화의 개념
  • 역할을 기반으로 불필요한 중복 코드를 제거하고 하나로 통합하는 것이 가능
  • 역할에 의해 변경과 확장이 용이한 유연한 설계가 가능함

 

객체 대 역할

  • 협력에 적합한 책임을 수행하는 댓아이 여러 종류면 역할이라고 부름
  • 협력에 적합한 책임을 수행하는 대상이 한 종류면 객체로 간주해도됨
  • 역할을 협력 안에서 각자의 위치를 가지는 객체들에 대한 별칭이라고 정의하기도 함

 

역할과 추상화

  • 역할의 큰 장점은 설계 요소를 추상화 할 수 있다는 것
  • 추상화의 장점과 동일한 장접을 갖게됨
    • 세부적인 사항을 무시하고 추상화에 집중할 수 있음
    • 설계를 유연하게 만들 수 있음

 

배우와 배역

  • 무대에서의 배우, 배역과 객체지향에서의 역할이 유사함
    • 객체는 협력(실행 문맥) 안에서 특정한 역할을 수행
    • 협력이 끝나면 원래의 객체로 돌아올 수 있음
    • 객체가 협력에 참여하는 동안에만 존재하는 일시적인 개념
    • 객체는 여러 역할을 가질 수 있으나 특정한 협력 안에서는 일시적으로 오직 하나의 역할만 바라볼 수있음

 

본 게시물은 조영호님의 저서 오브젝트를 학습하면서 정리한 내용입니다.

객체지향 개발자라면 꼭 알아야할 내용들이 가득한 책이기 때문에 참고만하시고 반드시 책을 구매해서 읽어보길 권해드려요!

(네이버 도서 구매링크 클릭)

저작물에 대한 문제가 발생할 경우 비공개 처리하겠습니다.


 

 

 

객체지향 프로그래밍을 향해

협력, 객체, 클래스

  • 객체지향은 객체를 지향하는 것
  • 프로그램을 작성할 때 클래스를 가장 먼저 떠올릴게 아니라, 객체 자체를 지향해야 함
    • 어떤 클래스가 아닌, 어떤 객체가 필요한지를 고민하라
      • 객체가 어떤 상태와 행동을 가지는지 결정
    • 객체를 기능 구현하기 위해 협력하는 공동체의 일원으로 보아라
      • 객체를 고립된 존재로 보면 안됨
      • 객체를 협력자로 바라보아야 함
    ⇒ 객체의 모양과 윤각이 잡힌 후, 공통된 특성과 상태를 가진 객체들을 타입으로 분류 → 이 타입을 기반으로 클래스 구현

 

도메인의 구조를 따르는 프로그램 구조

  • 도메인은 문제를 해결하기 위해 사용자가 프로그램을 사용하는 분야
  • 일반적으로 클래스의 이름은 대응되는 도메인 개념의 이름과 동일 또는 유사하게 지어야 함 클래스 사이의 관계도 최대한 도메인 개념의 관계와 유사하게 만들어야 함→ 프로그램 구조를 이해하기 쉽고 예상 가능하게 만들기 위함⇒ 현실의 도메인 구조와 동일하게 매핑되어 있는 클래스 구조

 

클래스 구현하기

  • 도메인 개념들의 구조를 반영하는 적절한 클래스 구조를 만든 후 → 적절한 프로그래밍 언어로 구현
  • 클래스를 구현할 때 가장 중요한 것 : 클래스 내부와 외부의 경계를 지어주는 것
    • 어떤 부분을 외부에 공개할지 정하는 작업
    ex)

자율적인 객체

  • 객체는 상태행동을 함께 가지는 복합적인 존재
  • 객체는 스스로 판단하고 행동하는 자율적인 존재

⇒ 객체지향이란 객체라는 단위 안에 데이터와 기능을 한 덩어리로 묶음으로써 적절하게 표현

  • 스스로 상태를 관리하고, 판단하고, 행동하는 자율적인 객체 공동체 구성하는 것
    • 외부에서 객체가 어떤 상태인지, 어떤 생각을 하고있는지 알면 안 됨
    • 직접적으로 개입해도 안 됨

 

프로그래머의 자유

  • 프로그래머의 역할
    • 클래스 작성자
      • 프로그램에 새로운 데이터 타입 추가
      • 클라이언트 프로그래머에게 필요한 만큼만 공개 (구현은닉) → 클라이언트 프로그래머에 대한 영향 최소화
    • 클라이언트 프로그래머
      • 클래스 작성자가 추가한 데이터 타입 사용
      • 필요한 클래스들을 엮어 애플리케이션 구축
      • 내부의 구현은 무시하고 인터페이스만 구현하여 프로그램 구축 → 코드를 자유롭게 수정 가능
    ⇒ 클래스를 개발할 때마다 인터페이스와 구현을 깔끔하게 분리하기 위한 노력을 해야 함
  •  
  • 설계가 필요한 이유는 변경을 관리하기 위함 → 파급효과를 제어, 변경으로 인한 혼란 최소화
💡
프로그래머의 역할을 나누는 시각이 참신하다. 프로그래머의 역할을 나누게되니 설계를 더 명확하게 바라볼 수 있는 것 같다. 간혹 우리는 클래스작성자가되기도 하고 동시에 클라이언트 프로그래머가 되기도 한다. 이 때, 역할을 머릿속으로 나누어 두었다면 구현하는 과정에서도 명확하게 외부와 내부를 구분하여 개발할 수 있지 않을까

 

협력하는 객체들의 공동체

  • 객체지향은 도메인의 의미를 풍부하게 표현할 수 있음
  • 어떤 기능을 구현하기 위해 객체들 사이에 상호작용을 함 (협력)
  • 협력 중심의 프로그래밍
    • 협력관점에서 어떤 객체가 필요한지 식별
    • 객체들의 공통상태, 행위를 구현하기위한 클래스 작성
  • 추상화, 상속, 다형성을 활용해 위임을 함 → 객체 간의 협력
    • 추상클래스
      • 여러 클래스의 중복 코드를 제거할 때 활용
      • 실제 애플리케이션에서는 추상클래스로 직접 인스턴스를 만들 필요가 없을 때 사용 가능
    • TEMPLATE METHOD 패턴
      • 부모 클래스에서는 기본적인 알고리즘 흐름을 구현,
      • 중간에 필요한 처리는 자식 클래스에게 위임하는 방식
    • ex) 직접 계산을 수행하지 않고 discountPolicy에게 위임

 

  • 생성자를 통해 객체 생성시 필요한 정보를 강제함 → 온전한 객체 생성 보장

 

💡
프로그램을 설계할 때, 협력을 염두에 두어야 한다. 구체적으로.. 협력관점에서 객체를 설계하고 책임에 따라 적절한 메서드를 수행할 수 있도록 위임해야 한다. 필요에 따라서는 패턴을 활용해서 위임이 적합하게 될 수 있도록 해야하고 생성자를 통해 객체가 온전하게 생성될 수 있도록 관리해야 한다.

 

 

 

 

상속과 다형성

  • 상속과 다형성을 사용해서 실행 시점에 의존성을 갖도록 구현

 

compile time 의존성 vs runtime 의존성

  • 의존성을 갖는 케이스
    • 어떤 클래스가 다른 클래스에 접근할 수 있도록 경로 가지고 있는 경우
    • 다른 클래스의 객체의 메서드를 호출하는 경우
  • 인스턴스 실행 시에 인스턴스간의 의존성 ≠ 코드 레벨에서 클래스 간의 의존성
    • ex)
    • discountPolicy에 의존하고 있고 discountPolicy의 상세 구현은 생성자를 통해 생성 시점에 결정됨
  • 클래스 사이의 의존성과 객체 사이의 의존성은 동일하지 않음
  • 클래스 사이의 의존성과 객체 사이의 의존성이 다를수록
    • 코드 이해가 어려워짐 (코드의 의존성 이외의 객체의 의존성까지 파악해야하기 때문)
    • 코드가 더 유연해지고 확장 가능해짐
  • 유연해질수록 디버깅이 어려워짐
  • 유연성을 억제할수록 디버깅은 쉬워지지만 확장 가능성과 유연성은 떨어짐

 

⇒ 트레이드 오프가 존재 → 무조건 유연한 것도, 무조건 읽기 좋은 것도 다 정답은 아님

💡
의존성을 두가지로 분리하고 일치하는지, 일치하지 않는지에 따라 분석하는 것이 인상깊다. 무조건 유연한 설계만을 추구하는 것이 옳은 것인가? 유연한 설계에 따라오는 댓가가 존재한다는 것을 잊고 있었다. 유연한 설계로 나아가되 어떤걸 트레이드오프했는지 정확하게 이해하고 있는 것이 중요하다.

 

차이에 의한 프로그래밍

  • 보모 클래스와 다른 부분만 추가해서 새로운 클래스를 얻어내는 것을 차이에 의한 프로그래밍이라고 함
  • 상속은 코드재사용에 널리 사용되는 방법
  • 기존 클래스가 가지고 있는 모든 속성과 행동을 물려받음
    • 기반 클래스를 통해 쉽고 빠르게 새로운 클래스를 추가할 수 있음

 

상속과 인터페이스

  • 상속이 가치있는 이유 : 부모 클래스가 제공하는 모든 인터페이스를 자식 클래스가 물려받을 수 있는 것→ 자식클래스는 부모클래스의 모든 메시지를 수신할 수 있음 ⇒ 외부 객체가 클래스를 부모클래스와 동일한 타입으로 간주함 (업캐스팅)
    • 일반적으로 코드를 재사용하기 때문에 가치있다고 보지만 이러한 관점과 거리가 있음
  • 구현상속 vs 인터페이스 상속
    • 구현상속 (서브클래싱) : 코드를 재사용하기 위해서 상속을 사용
    • 인터페이스상속 (서브타이핑) : 인터페이스를 공유하기위해서 상속
    → 코드 재사용을 상속의 목적으로 이해하면 안됨! (변경에 취약한 코드를 만들어지기 때문)인터페이스 상속을 위해 사용되어야 함

 

다형성

  • 메시지와 클래스가 다른 개념이라는 것에서부터 출발
  • 동일한 메시지를 수신하는 클래스에 따라서 다른 방식(메서드구현체)로 실행되는 것
  • 다형성으로 인해 컴파일 시간 의존성과 실행 시간 의존성이 달라짐
  • 메시지와 메서드를 실행 시점에 바인딩하게 함 ( 동적바인딩 or 지연바인딩)

 

인터페이스와 다형성

  • 순수하게 인터페이스만 공유하고 싶을 때 사용
  • 구현에 대한 고려 없이 다형적인 협력에 참여하는 클래스들이 공유 가능한 외부인터페이스 정의

 

💡
상속을 일반적의 코드의 재사용성 극대화하기 위해 생각하곤 했다. 하지만 상속이 가치있는 이유는 부모클래스에서의 메시지를 사용할 수 있다는 관점이 새로웠다. 오히려 소스를 재사용하면 강력하게 의존되기 때문에 변경에 취약하다는 것을 유의하자.

 

추상화와 유연성

추상화의 힘

  • 추상화 계층만 따로 떼어 놓고 살펴 볼 수 있음 → 요구사항의 정책을 높은 수준에서 서술
    • 새로운 클래스가 추가되더라도 상위 단계에서의 협력 흐름을 그대로 따름
  • 설계가 유연해짐
    • 구체적인 상황에 결합되는 것을 방지함
    • 조건문으로 분기하거나 기존 코드를 수정하는 것이 아닌 확장할 수 있음 → 협력의 일관성을 유지하기 쉬워짐
    • 컨텍스트 독립성 키워드 참고

 

추상 클래스와 인터페이스 트레이드오프

  • 구현과 관련된 모든 것들은 트레이드오프의 대상이 됨
  • 의도를 효과적으로 전달하고 코드가 명확해질 수 있지만 반대로 과잉 조치가 될 수 있음

 

코드 재사용

  • 코드 재사용에 가장 널리 사용되는 방법은 상속
  • 그렇지만 상속이 가장 좋은 방법은 아님
  • 상속보다는 합성
    • 합성 : 다른 객체의 인스턴스를 자신의 인스턴스 변수로 포함해서 재사용하는 방법

 

상속

  • 설계에 악영향
    • 상속은 캡슐화를 위반함
      • 부모클래스의 구현이 자식클래스에 노출됨
      • 캡슐화의 약화로 인해 부모클래스와 자식클래스가 강하게 결합될 수 있음
    • 설계를 유연하지 못하게 만듦
      • 상속으로 인한 클래스간 관계는 컴파일 시점에 결정됨 → 실행시점에 변경하는 것이 불가능

 

합성

  • 인터페이스를 통해 약하게 결합
  • 상속에서의 두가지 문제를 해결함
    • 인터페이스 메시지를 통해 재사용하기 때문에 효과적인 캡슐화 가능
    • 메시지를 통해 느슨하게 결합 → 설계 유연 해짐

 

코드를 재사용하기 위해선 상속보단 합성

다형성을 위해 인터페이스를 재사용하는 경우 상속과 합성을 조합해서 사용할 수 있음

 

💡
상속보단 합성이라는 이 유명한 말에 대해서 ‘왜?’라는 의문을 제대로 던져 보지 않았다. 이유있는 소스라는 건 별 것 아닌것 같아보이거나 당연해 보이는 것에 대해서도 물음을 던져봐야 하는게 아닐까? 결합도가 높아진다는 것 이면에 존재하는 근본적인 이유는 상속을 하면 부모의 클래스에 자식 클래스가 직접 접근하는데에 있다. 유연한 설계는 런타임과 컴파일시간의존성이 달라야 하는데 상속은 같을 수밖에 없다는 부분은 생각을 못했던 부분이기도 하다.

 

 

 

본 게시물은 조영호님의 저서 오브젝트를 학습하면서 정리한 내용입니다.

객체지향 개발자라면 꼭 알아야할 내용들이 가득한 책이기 때문에 참고만하시고 반드시 책을 구매해서 읽어보길 권해드려요!

(네이버 도서 구매링크 클릭)

저작물에 대한 문제가 발생할 경우 비공개 처리하겠습니다.


소프트웨어의 3가지 목적 - 마틴

  1. 실행 중에 제대로 동작하는가 (제대로 실행되어야 한다.)
  1. 변경을 위해 존재하는가 ( 변경에 용이 해야한다.)
  1. 특별한 훈련이 없어도 개발자가 쉽게 읽고 이해할 수 있는가 (이해하기 쉬워야 한다.)

 

💡
목적을 잃은 물건은 금방 의미를 상실한다 소프트웨어도 마찬가지인 것 같다. 내가 만드는 소프트웨어는 그 목적을 잘 달성하는가? 3가지 목적이 기준이 된다면 내가 만드는 소프트웨어는 의미를 찾을 수있지 않을까
💡
소프트웨어의 존재 이유를 변경을 위해서 존재한다는게 인상깊다

 

책 속 예제

  • before : theater의 의존관계가 과하게 많음

 

예상을 빗나가는 코드 - 이해하기 어려운 코드

  • 이해 가능한 코드란 그 동작이 우리의 예상을 크게 벗어나지 않는 코드다.
  • 코드의 진행이 상식을 벗어나기 시작하면 코드를 읽는 사람과 의사소통이 어려워 질 수 있다.
  • 코드를 이해하기 위해서 한번에 여러가지 세부 사항을 기억해야 한다면 이해하기 어렵다.
    • 하나의 클래스나 메서드에서 너무 많은 세부사항을 다루면, 이해가 어려울 뿐 아니라 변경에도 영향을 미친다.

 

변경에 취약한 코드

  • 다른 클래스의 세부적인 내용을 많이 알수록 변경이 어려워진다 → 그렇다고 무작정 의존관계를 없애는 것은 정답이 아니다 "최소한의 의존성만 유지하도록 하는 것"

 

  • 의존성은 변경과 관련되어 있음 → 의존성은 변경에 대한 영향을 암시 ”의존성이라는 말 속에는 어떤 객체가 변경될 때 그 객체에게 의존하는 다른 객체도 함께 변경될 수 있다는 사실을 내포하고 있다.”

 

해결방법 : 자율성을 높이자

  • 객체 스스로가 자신의 정보를 처리하도록 만드는 것 객체를 자율적인 존재로 만들면된다.
  • 자율적인 존재를 만든다는 것은 외부에서 구체적인 정보까지 직접 접근하는 것을 차단하고 정보를 갖고있는데 객체에 의해서 정보가 나갈 수 있게 만드는 것
  • 객체가 수동적이면 다른 객체에서 세부적인 정보까지 알고 있어야 하기 때문에 필연적으로 변경에 취약해진다.
  • 다른 누군가의 통제를 받는다는 것은 객체사이에 의존성이 생겼다는 말이다.

 

예시

 

 

 

 

 

  • 해당 소스에서 다양한 문제가 있지만, 대표적인 문제로 의존성의 문제를 들 수 있다.
    • 대표적인 예로 영화관에 입장하는데 ticketSeller 가 있고, ticketSeller한테 ticketOffice 정보를 받고, ticketOffice가 갖고있는 ticket을 준다는 걸 영화관이 다 알고 있다는 점이 문제이다.
      • 만약 ticketOffice말고 다른 방식을 통해서 ticket을 받게 된다면?→ getTicketOffice()~ 소스는 삭제되어야 한다.
      • 만약 ticketOffice 말고 다른 방식도 가능하게 변경된다면?→ if문으로 분기처리를 해서 getTicketOffice() 외에도 다른 방식도 추가하게 된다.

      ⇒ Theater입장에서는 몰라도 되는 구현때문에 본인의 소스가 바뀌어야 하는 상황을 맞이할 수 있음
    • Bag 도 동일한 이유로 문제가 발생한다.
  • 캡슐화를 통해 구체적인 구현에 숨기고 결합도를 낮춘다.
  • 캡슐화의 목적은 결합도를 낮추고 변경하기 쉬운 코드를 만드는 것

 

💡
객체 내부의 속성을 무작정 getter 로 다 내보내주는 것은 어떤면에선 무책임한 것 일 수도 있다는 생각이 든다. 객체는 각자가 책임을 다해야 한다. 단순히 데이터를 잡아두고 있다가 무책임하게 날 것 그대로를 반환한다면 수동적인 존재로 변경에 걸림돌이 된다.

 

캡슐화와 응집도

  • 객체 내부의 상태를 캡슐화 하고 오직 메시지를 통해서만 상호작용하도록 만듦
  • 밀접하게 관련있는 작업만 수행하고 연관성이 없는 작업은 다른 객체에게 위임 → 응집도를 높임
  • 객체의 자율적이게 만듦

 

절차지향과 객체지향

  • 프로세스와 데이터의 위치로 구분
  • 절차지향 : 데이터와 프로세스가 별도의 모듈에 위치함 모든 처리가 하나의 클래스 안에 위치 함, 처리를 실행하는 클래스를 제외한 나머지 클래스는 단순히 데이터의 역할만 수행 ( getTicket() 메서드를 쓰면 ticket 객체를 전달해주 듯 단순힌 데이터로의 역할)
  • 객체 지향 : 데이터와 프로세스가 동일한 모듈 내부에 위치

 

 

좋은 설계

  • 캡슐화를 이용해 의존성을 적절히 관리 → 객체사이의 결합도 낮추고 응집도를 높임
  • 자신의 문제를 스스로 처리해야 함
  • 객체 내부의 변경이 객체 외부에 파급되지 않도록 제어

 

책임의 이동

  • 책임이 집중되어 있다는 건 한 곳에서 집중적으로 제어를 하고 있다는 것
  • 객체지향설계에서는 기능을 완성하기 위해서 분산되어 있는 여러 책임이 협력함
  • 객체지향설계는 책임이 개별 객체로 이동함→ 객체는 자신을 스스로 책임진다.
  • ⇒ 데이터와 프로세스를 하나의 단위로 통합해놓는 방식
  • 어떤 데이터를 가지냐 보다 어떤 책임을 할당할 것인지에 집중하는 것 필요

 

이점

  • 책임이 이동함에 따라 코드는 더 이해하기 쉬워짐
  • 변경에 탄력적인 대응이 가능해짐→ 견고한 설계

 

주의점

  • 설계에는 명확한 정답이 있는 것이 아님
    • 설계는 트레이드오프의 산물 ⇒ 어떠한 경우에도 모든 사람을 만족시킬 수 없음
    • 균형을 맞추는 것

 

객체지향설계

  • 의존성을 효율적으로 통제 → 변경에 유연하게 대응할 수 있는 코드를 작성
    • 변경에 유연하게 대응할 수 있는 코드
      • 이해하기 쉬움
      • 느슨한 결합

 

 

# 콘솔창

10월 17, 2021 2:02:10 오전 org.junit.platform.launcher.core.EngineDiscoveryOrchestrator lambda$logTestDescriptorExclusionReasons$7

정보: 0 containers and 3 tests were Method or class mismatch

 

인텔리J 로 테스트케이스를 작성하는데 자꾸 나오는 문구!!

그렇다고 테스트 케이스가 실패나거나 안되는건 아닌데,

콘솔에 자꾸 빨간색으로 나오니 신경쓰여서 찾아보았다

 

 

원인

 

이 오류는 여러개의 테스트케이스를 작성해놓고

인텔리J 편의기능으로 하나의 테스트만 눌러서 실행했을 때 발생하는 것을 확인했다.

 

정확하게 확신은 없지만.. (댓글로 설명해주시면 수정할게요! ㅎㅎ)

 

인텔리J 편의 기능을 사용해서 하나의 테스트만

콕 집어서 테스트케이스를 실행하면

어쨌든 빌드는 해야하는데 전체 빌드하는 것도 아니고 하니

인텔리J가 자체의 빌드기능으로 빌드를 해서 실행해주는 것 같다.

 

내 설정의 기본 빌드툴은 Gradle인데 

갑자기 다른 빌드툴로 빌드를 하니

Method가 Missmatch 났다고 알려주는 것같다.

 

 

참고 : https://www.inflearn.com/questions/157200

 

 

 

 

 

 

 

 

 

해결방법

빌드툴을 그냥 인텔리J 꺼로 쓰라고 변경해주면

이런 MissMatch가 없어지는 것 같다.

 

위의 설정을 아래와 같이 변경하면 된다.

 

 

 

 

도움이 되는 글이었다면

로그인이 필요없는 공감 버튼 꾹 눌러주세요! 

 

 

 

 

 

1. 구매 계기

키크론 키보드 K8를 사전예약으로 구매하면서부터 

지티기어라는 곳에서 광고 메일이 한 번씩 왔어요..

(컴퓨터 주변기기 유통사 같아요!)

 

우연히 본 광고 메일에서 모니터암의 존재를

알게 됐고 결국 구매까지 이어졌답니다ㅋㅋㅋㅋ

 

 

지티기어 [지티기어 짱모니터암 스탠드 모니터 거치대]

지티기어 [지티기어 짱모니터암 스탠드 모니터 거치대]  

www.gtgear.co.kr

 

 

 

 

2. 만족도 

 

 

1) Before

 

 

 

2) After

 

 

 

 

 

만족도는 최상이에요!

사실 꼭 '짱 모니터암'이라서가 아니라

모니터암이라는 물건 자체가

엄청난 만족을 주는 것 같아요

 

무엇보다도 책상을 넓게 쓸 수 있고 

적당한 높이를 특별한

제약 없이 움직일 수 있어서

장시간 모니터를 보고 있기에 

목에 부담도 덜해요.

 

 

 

 

 

 

 

 

 

근데 아무래도 모니터암은 

기둥만으로 모니터를 받치고

있어야 하기 때문에 안정감이

필수인 것 같은데

 

그런 점에서 

지티기어 짱모니터암이

괜찮은 것 같아요.

저는 이 제품 추천이에요!

 

 

 

3. 장점

1) 가격

모니터암을 네이버에 검색해보면

가격이 천차만별이에요 

싼 건 2만 원 대도 있고

비싼 건 10만 원, 20만 원도

하더라고요!

 

 

 

 

근데..

너무 싸면 의심스럽고 

너무 비싸면 부담스럽고..

사람 마음이라는 게 참..ㅎㅎㅎ

 

제 모니터는 29인치인데 

이 정도 모니터에는 3만 원대가 

적당하다고 생각했고

3만 원대 모니터암 중에는 

여기 제품이 제일

괜찮은 것 같았어요!

 

 

 

 

2) 퀄리티

 

지티기어가 어떤 곳인지는

정확히 잘 모르지만

키크론이라는 키보드를

유통하는 것 같은데

여기서 구매하고 너무 만족스럽게

쓰고 있어서 믿고 샀어요

역시나...

 

무엇보다도 제품 퀄리티는 괜찮아요

무게감 꽤 있어서 고정도 잘 되고 

중심을 잘 잡아주는 느낌이에요!

 

 

 

 

 

 

 

 

3) 위치 조정 가능

 

 

 

 

적당한 위치 조절할 수 있게 되어있어서

생각보다 편하더라고요 

높낮이뿐 아니라 

모니터 고개를 위아래로

각도 조절이 가능해서

원하는 포지션을 잡기에 충분해요!

 

 

 

 

4. 주의할 점

1) 책상 사이즈

 

 

 

 

책상의 두께는 웬만한

책상은 다 가능할 것 같은데 

모니터 암이 책상을 집을 공간이

넉넉하게 확보되어야 해요 

제품 스펙을 보면 얼마만큼

집는지 보일 테니까 

(모니터암 집게 부분 폭)

그걸 보고 잘 확인하고

구매하시길 추천해요

 

 

 

2) 조립

 

 

 

 

조립이 생각보다 쉽지 않아요

물론 조립에 대한 설명서가 잘 있지만

저는 원래 조립을

잘못하는 편인가 봐요..ㅋㅋㅋㅋ

조립해서 설치하는데만 

한참 걸렸네요 ㅠㅠ

 

 

5. 추천 대상

1) 장시간 모니터를 보고 있는 직업

2) 책상을 넓게 쓰고 싶으신 분

3) 컴퓨터 자세를 바로 잡고 싶으신 분

4) 깔끔하게 정리하는 걸 좋아하는 분

구매 관련 링크

지티기어

지티기어 레이싱 & 게이밍 전문 스토어. 파나텍, 스파르코, 플레이시트, 트러스트마스터, 커세어, 프나틱 전문.

www.gtgear.co.kr

 

 

 


 

 

 

참고 

 

 

 

 

참고로 후기글을 쓰면

지티기어에서 선물을 주는

이벤트가 있더라고요.

그래서 이벤트 응모하려고

귀찮음을 이겨내고 리뷰를 써봤습니다.

리뷰를 잘 쓴다고 해서

뭘 더 주고 그러는 건 아니고 

정말 양심적으로 잘 쓰고 있어서

오랜만에 제품 리뷰해봤어요! ㅎㅎ

 

 

 

 

 

 

 

단축키를 잘 사용하면

드라마틱하게 생산성을 높일 수 있다.

 

자주 쓰는 단축키를 모아놓고 외워두자!

 

 

실행 내용

Windows 단축키

Mac OS 단축키

단위선택

Ctrl + W

Option + Up

라인삭제

Ctrl + Y

Cmd + Del

코드재정렬

Ctrl + Alt + L

Cmd + Option + L

Multi Selection

Ctrl * 2 + Up / Down

 

OR

 

Alt + Drag

Option * 2  + Up / Down

 

OR

 

Option + Drag

부분적으로 다중선택

Alt + shift

Option + Shift

밑에있는같은키워드선택

Alt + J

Ctrl + G

같은키워드전체선택

Shift + Ctrl + Alt + J

Ctrl + Cmd + G

히스토리에서 붙여넣기

Ctrl + Shift + V

Cmd + Shift + V

스네이크 케이스

 -> 카멜케이스변환
(플러그인설치
사용)

Shift + Alt + U

Option + Shift + U

라인단위코드위치옮기기

Alt + Shift + Up / Down

Alt + Shift + Up / Down

메서드단위
코드위치옮기기

Ctrl + Shift + Up / Down

Cmd + Shift + Up / Down

메서드단위로커서옮기기

Alt + Up / Down

 

메서드선언위치로이동

Ctrl + B

Cmd + B

인터페이스구현부이동

Ctrl+ Shift + B

Cmd + Shift+ B

 

 

 

 

 

 

 

 

실행 내용

Windows 단축키

Mac OS 단축키

프로젝트탭

Alt + 1

Cmd + 1

구조탭

( 변수, 메서드한눈에보기)

Alt + 7

Cmd + 7

계층보기

Ctrl + H

Ctrl + H

활성 또는 마지막 활성 
도구 창 숨기기

Shift + ESC

Shift + ESC

매개변수표시

Ctrl + P

Cmd + P

코드 감싸기(if ..)

Ctrl + Alt + T

Cmd + Option + T

메서드로 만들기

Ctrl + Alt + M

Cmd + Option + M

Join Line

Shift + Ctrl + J

Shift + Ctrl + J

반복되는구문변수로 생성

Ctrl + Alt + V

Cmd + Option + V

Postfix Completion

다양한상용구세팅에서확인

라이브템플릿지정

자주사용하는템플릿지정(ex. llv, llh)

 

 

 

** 카멜 케이스 플러그인 설치

plugin -> market place -> CamelCase 설치

 

 


 

 

 

 

 

도움이되는 글이었다면

로그인이 필요없는 공감 버튼 꾹 눌러주세요! 

 

 

 

 

 


많은 시간을 들인 게시글입니다. 

무단으로 복사해서 게시하지 말아 주세요.


1.에러발생 

앞선 글에서 자체 인증서를 통한 Retrofit 통신 시

발생하는 에러에 대한 해결을 올렸다. 

 

 

[Android] Retrofit - SSL 에러 해결 : Trust anchor for certification path not found.

 

[Android] Retrofit - SSL 에러 해결 : Trust anchor for certification path not found.

많은 시간을 들인 게시글입니다. 무단으로 복사해서 게시하지 말아 주세요. 앱과 서버를 만들어서 HTTP로 통신하게 만들었다. 만들고 나니 HTTPS로 통신하게 만들고 싶어 졌다. 그리고 문제가 생겼

kyome.tistory.com

 

이 문제의 연장선으로 자체인증서를 가진 서버에

Glide를 이용해 HTTPS URL로 이미지를 가져오려고 하면 

다음과 같은 에러가 발생한다.

 

 

 

 

 

"I/Glide: Root cause (1 of 1) javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found."

 

 

 

 

그리고 화면은 아래와 같이 아무 이미지도 가져오지 못한다.

 

 

 

 

 

 

2. 해결 방안

Glide에 지정한 OkHttpClient를 가지고

통신하게 코드를 변경해주면 된다.

 

OkHttpClient에 설정을 변경하여

자체 인증서를 사용하는 서버와 HTTPS 통신이

가능하게 해주고 (이전 게시글에서 적용했던 방식)

이렇게 만든 OkHttpClient를 Glide 통신할 때 사용하도록

지정해주면 해결할 수 있다.

 

 

 

 

3. 상세 방법 및 소스

1) OkHttpClient 세팅 클래스 선언

 

이전 게시글에서 

 

[Android] Retrofit - SSL 에러 해결 : Trust anchor for certification path not found.

많은 시간을 들인 게시글입니다. 무단으로 복사해서 게시하지 말아 주세요. 앱과 서버를 만들어서 HTTP로 통신하게 만들었다. 만들고 나니 HTTPS로 통신하게 만들고 싶어 졌다. 그리고 문제가 생겼

kyome.tistory.com

 

4. 상세 방법 및 소스

  1) raw 디렉터리에 crt 인증서 넣기

  2) 자체 인증 빌더 클래스 생성

  4) Hostname (ip) not verified 에러

 

까지 작업해두기 

 

 

 

 

 

 

 

 

 

 

 

2) build.grade 에 dependency 추가

 

// build.gradle (:app)

dependencies {
	...
	
    implementation 'com.github.bumptech.glide:okhttp3-integration:4.6.1'
	
    ...
}

 

 

 

 

3) GlideModule 클래스 생성

 

@GlideModule
public class SSLGlideModule extends AppGlideModule {
    @Override
    public void registerComponents(
    	@NonNull Context context,
        @NonNull Glide glide, 
        @NonNull Registry registry) {
        
          super.registerComponents(context, glide, registry);

          // OkHttpClient Builder에 
          // 자체인증서 HTTPS 통신하도록 설정
          SelfSigningHelper helper = SelfSigningHelper.getInstance();
          OkHttpClient.Builder builder = new OkHttpClient.Builder();
          helper.setSSLOkHttp( builder,"10.0.2.2");

          registry.replace(GlideUrl.class, InputStream.class,
          	new OkHttpUrlLoader.Factory(builder.build()));
    }
}

 

참고자료 : Gilide공식문서

 

Glide v4 : Configuration

Setup Starting in Glide 4.9.0, setup is required in a couple of cases. For applications, setup is only required if the application wants to: Use one or more integration libraries Change Glide’s configuration (disk cache size/location, memory cache size e

bumptech.github.io

 

 

 

 

5) 사용하기

 

이렇게 준비했다면 사용하는 건 완전히 동일하다.

 

Glide.with(getApplicationContext())
  .load(Config.BASE_URL).into(imageView);

 

 

 


 

 

 

 

도움이 되는 글이었다면

로그인이 필요없는 공감 버튼 꾹 눌러주세요! 

 

 

 

 

+ Recent posts

"여기"를 클릭하면 광고 제거.