개발 서적 기록/오브젝트_조영호

2일차 - 객체 지향적인 모듈

밍 끄적 2023. 8. 2. 02:33
728x90

 

2023.08.01 TUE

2p ~ 16p

 

1일차 내용 ⬇️

2023.07.31 - [개발 서적 기록/오브젝트_조영호] - 1일차 - 오브젝트를 본격적으로 읽기 전에

 

1일차 - 오브젝트를 본격적으로 읽기 전에

2023.07.31 MON 전반적인 내용 오브젝트 책은 '객체 지향 프로그래밍'에 대한 개념을 다루는 책이다. 구체적으로는 아래의 내용을 포함하고 있다. - 역할, 책임, 협력에 기반해 객체지향 프로그램을

magenta-ming.tistory.com


소프트웨어 모듈

크기와 상관없이 클래스나 패키지, 라이브러리와 같이 프로그램을 구성하는 임의의 요소

 

소프트웨어 모듈의 기능/목적

from 로버트 마틴의 "클린 소프트웨어: 애자일 원칙과 패턴, 그리고 실천방법"

1. 실행 중에 제대로 동작해야한다.

요소가 정상적으로 동작하는 것은 모듈의 기능을 수행하기 위한 당연한 일이다. 모듈의 존재 이유이다.

2. 이해하기 쉬워야한다.

가독성이 좋은, 흐름과 로직이 잘 이해가 되는 모듈은 의사소통할 수 있는 모듈이다.

이해 가능한 코드는 내부 흐름, 동작이 예상에서 크게 벗어나지 않아야한다.

 

예제를 보면, 소극장에서 티켓을 예매하는 기능을 수행할 때 아래와 같은 흐름으로 구성되어 있다.

소극장은 관람객의 가방을 열어, 그 안에 초대장이 들어 있는지 살펴본다.
가방 안에 초대장이 들어있으면 판매원을 매표소에 보관되어 있는 티켓을 관람객의 가방 안으로 옮긴다.
가방 안에 초대장이 들어 있지 않다면, 관람객의 가방에서 티켓 금액만큼의 현금을 꺼내, 매표소에 적립한 후에, 매표소에 보관되어 있는 티켓을 관람객의 가방 안으로 옮긴다.

실제 상황이라고 생각한다면, 위 흐름은 어색하다는 것을 알 수 있다.

아래와 같은 이유로, 예상에서 벗어낫기에 잘못된 소프트웨어 모듈로 간주한다.

- 소극장은 관람객의 허락없이, 직접 가방을 열어보지 않아야한다.

- 소극장은 판매원의 허락없이, 직접 매표소의 티켓과 현금에 접근, 관리하지 않아야한다.

 

또, 너무 많은 여러 내용을 한번에 기억한 채 코드를 이해해야하는 경우에도, 잘못된 소프트웨어 모듈로 간주한다.

동일한 예제에 대해, 소극장 클래스 Theater Class를 선언하였다.

public class Theater {
	
    private TicketSeller ticketSeller;
    
    public Theater(TicketSeller ticketSeller) {
    	this.ticketSeller = ticketSeller;
    }

    public void enter(Audience audience){
        if(audience.getBag().hasInvitation()){
            Ticket ticket = ticketSeller.getTicketOffice().getTicket();
            audience.getBag().setTicket(ticket);
        }
        else{
            Ticket ticket = ticketSeller.getTicketOffice().getTicket();
            audience.getBag().minusAmount(ticket.getFee());
            ticketSeller.getTicketOffice().plusAmount(ticket.getFee());
            audience.getBag().setTicket(ticket);
        }
    }
}

이 클래스의 enter 메서드를 이해하기 위해서는 Audience, Bag, Bag 내부에 현금과 티켓 필드가 있다는 것, TicketSeller는 TicketOffice에서 티켓을 판매한다는 점 등등 여러 사실을 동시에 기억해야한다.

 

따라서 하나의 클래스나 메서드에서 너무 많은 세부사항을 다루지 않도록해, 이해에 대한 부담을 줄여야한다.

3. 간단하게 변경할 수 있어야한다.

모듈은 생명주기 내에서 변경이 이루어지므로, 간단히 변경할 수 있어야한다.

 

변경에 취약한 코드는 요구사항이 변하게 되었을 때 무너져내릴 수 있다.

 

변경에 취약한 코드는 특정 객체에 대한 의존성이 높을 때에 발생할 수 있다.

세부적인 사실 중에 한 가지라도 바뀐다면, 해당 클래스 뿐만 아니라, 이 클래스에 의존하는 다른 객체들도 함께 변경해야하기 때문이다.

즉, 의존성은 변경에 대한 영향을 가지고 있다.

 

그래서 이러한 의존성을 낮춰야하는, 즉 결합도(coupling)을 낮춰야한다.

객체 지향 설계를 수행해야하므로 각 객체 간에 어느 정도의 협력은 필요하기에, 의존성을 완전히 없애서는 안된다.

하지만 최소한의 의존성은 유지하고, 불필요한 의존성을 제거해 결합도를 찾춰야한다.

 

따라서, 객체 사이의 결함도를 낮춰서 변경이 용이한 설계를 만들어야한다.


클래스와 모듈의 차이

클래스는 객체를 만들기 위해서 선언하고, 모듈은 클래스에 기능을 제공하기 위해서 선언한다.

모듈을 어떠한 기능을 하는, 사용가능한 메서드를 제공하는 라이브러리라고 간주한다.

  클래스 모듈
인스턴스화 가능 불가능
메서드 클래스 메서드, 인스턴스 메서드 모듈 메서드, 인스턴스 메서드
상속 가능 불가능
extend 불가능 가능
728x90