앱 개발 개척시대
K리그 프로그래머
2장에서 예제로 영화 예매 시스템을 만들어 본다.
도메인 지식
영화, 상영, 가격, 할인 조건, 할인 정책에 관한 도메인이 있다.
영화는 여러번 상영할 수 있다.
영화에는 하나의 할인 정책만 할당할 수 있다
할인 정책에는 금액 할인과 비율 할인이 있다
할인 조건은 여러가지를 적용할 수 있다
할인 조건에는 순번 조건, 기간 조건이 있다
할인 정책이 없는 경우도 있다. 이 경우 당연히 할인 조건을 붙여봐야 할인이 안되므로 할인 조건도 없다.
도메인이란?
> 문제를 해결하기 위해 사용자가 프로그램을 사용하는 분야
객체 지향은 객체를 지향한다는게 무슨 말인가?
> 지향은 어딘가로 향한다는 말이다. 어디로 향하는가?
> 여러 객체가 자신의 목적을 이루기 위해 다른 객체를 향해 있다는 말이다.
> 객체 지향은 이러한 객체간의 협력으로 앞에 놓여진 문제를 해결하기 위한 방법이다.
객체지향 패러다임을 적용할 때 주의점 2가지
> 클래스보다 객체를 먼저 생각하라.
> 객체를 독립적인 개체가 아니라 협력하는 공동체의 일원으로 여겨라.
객체지향의 추상화 기법
객체지향에서는 `객체`라는 추상화 기법을 계속 사용한다.
객체는 상태와 행동을 동시에 가진 복합적인 녀석이다. 또한 스스로 판단하고 행동하는 자율적인 존재이다. (이건 솔직히 저자가 좀 오바한다고 생각했다.)
캡슐화
캡슐화 + 접근제어는 객체를 두 부분으로 나눈다. 하나는 외부에서 접근 가능한 퍼블릭 인터페이스, 다른 하나는 내부에서만 사용하는 구현이다. 인터페이스와 구현의 분리 원칙은 객체지향에서 핵심적인 원칙중 하나이다. 일반적으로 상태(변수)는 숨기고 행동(메서드)은 공개한다. 메서드는 객체가 수신된 메시지를 처리하는 자신만의 방법이다.
상속과 다형성
Movie클래스는 생성자에 할인정책(DiscountPolicy)을 전달하도록 되어 있다. 할인정책은 금액할인 혹은 비율할인 정책인데 그런 정보가 Money의 생성자에는 없다.
```
Movie(String title, Duration runningTime, int fee, DiscountPolicy discountPolicy)
```
그렇지만 잘 동작하는데 이유는 컴파일 시간이 아닌 실행시간에 해당 클래스의 실제 타입과 메서드를 바인딩 시켜주기 때문이다. 이를 지연 바인딩 혹은 동적 바인딩이라고 한다.
상속과 인터페이스
상속이 가치 있는 이유는 코드의 재사용이 아닌 인터페이스의 재사용이다.
인터페이스는 객체가 이해할 수 있는 메시지의 정의이다.
부모 클래스를 상속을 받은 자녀 클래스를 사용하는 외부 클래스는 해당 클래스가 부모인지 자녀인지 상관없이 메시지를 수신할 수 있는 여부에만 관심이 있다.
오버로딩과 오버라이딩
오버로딩은 메서드 명은 같지만 메서드 시그니처가 다른 것
오버라이딩은 부모 클래스의 메서드를 자녀 클래스에서 재구현하는 것
추상화와 유연성
추상화를 사용할 경우의 장점
요구사항을 높은 수준에서 서술 할 수 있다.
설계가 유연해진다.
유연한 설계
할인 정책이 없는 경우의 처리를 어떻게 할 것인가?
예외 케이스는 최소화하고 일관성을 유지할 수 있는 방법을 선택하라.
템플릿 메서드 패턴으로 만들어놔서 쉽게 수정 가능함
기존 : 예외처리 >> 수정 : 할인이 없는 정책을 표현하는 클래스를 추가
할인 정책을 인터페이스로 변경하고, 하위에 할인이 없는 클래스와 있는 클래스로 하는 방법도 가능
구현은 결국은 트레이드 오프이다.
코드의 재사용
코드를 재사용하는 방법으로 상속을 사용하는 것은 좋지않다.
캡슐화를 위반함 (자녀클래스에 부모클래스의 내부구조가 오픈됨)
부모와 자녀 클래스가 강결합되어 있어서, 수정시 둘다 수정해야함
위 두가지 이유로 설계가 유연하지 않다.
책에는 실행시점에 자녀클래스로 못바꾼다고 되어 있는데 이건 잘 못된 내용 같음. 추상클래스로 예제도 만들었슴시롱.
대신 합성을 사용하자.
구현의 캡슐화가 가능
설계가 유연해진다.
인터페이스와 구현 클래스는 서로 느슨하게 결합됨
실제 코드를 작성할 때는 상속도 쓰고 인터페이스도 쓰고 적절하게 잘 쓰면 된다.
상속이나 합성은 객체의 관계와 상호작용을 먼저 생각하고 나서 결정해도 된다.
변수를 private으로 선언한뒤 getter, setter를 만드는 것과 그냥 변수를 public으로 선언하는 것에는 어떤 차이가 있을까?
> 객체의 자율성이 보장이 되느냐의 차이가 있다.
> 변수가 private인 경우에는 getter, setter를 각 객체에 맞는 방법으로 만들 수 있지만,
> 그냥 public 변수인 경우에는 다른 객체가 마음대로 값을 읽고 변경할 수 있으므로 자율성을 침해당한다.
> 그런데 그렇게 하는게 맞는 경우도 종종 있는 것 같다.
템플릿 메서드 패턴이란?
> 전체 처리의 구조를 만들어둔 추상 클래스를 만들고 실제로 변경되는 부분만 자녀 클래스에서 구현하도록 하는 패턴 책에서는 할인 정책관련된 클래스 코드를 작성할 때 사용되었다.
복잡도가 있지만, 논리적으로 깔끔한 설계와 반면 이해가 쉽지만 예외처리를 추가해야하는 코드중에 어떤 것을 선호하는가?
> 개인적으로는 무조건 이해가 쉬운 것을 선호한다. 물론 논리적으로도 깔끔하면서 이해도 잘 되는 코드가 베스트이다.
구현체가 딱 하나만 있는 인터페이스는 있는게 좋을까?
> 경우에 따라 다른 것 같다. 추후에 구현체가 늘어날 것 같다면 인터페이스가 의미가 있을 것이고, 아니라면 굳이 인터페이스를 만들 필요가 있을까.
이전 게시글
오브젝트 1장 https://careerly.co.kr/comments/92380
다음 내용이 궁금하다면?
이미 회원이신가요?
2023년 10월 18일 오후 4:09