본문 바로가기

책/오브젝트 (완)

1장 객체, 설계

주요 키워드

  • 자율성
  • 캡슐화
  • 응집도
  • 객체지향
  • 책임의 이동
  • 의존성
  • 의인화
  • 데이터, 프로세스

 

해당 장에서 제시하는 코드는 "자율성", "책임", "응집도"등 모든 면에서 객체지향스럽게 작성하지 않은 코드들입니다.

즉 해당 코드에서 나타나는 여러 문제점들을 차차 수정해나가며 공부를 해나가도록 저자는 유도를 하고 있습니다.

그리고 저는 이를 따라가고자 합니다.

 

1장에서 구현한 프로그램은 티켓을 판매하는 프로그램으로 UML은 다음과 같습니다.

 

그리고 이러한 UML을 바탕으로 구현한 코드는 다음과 같습니다.

public class Theater {
    private TicketSeller ticketSeller;

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

    /**
     * @param audience-티켓을 구매하려는 Audience 객체
     * 극장에 입장할 때 audience 가 가지고 있는 bag 객체에서 각각을 조회
     * 초대장이 있을 떄 : 초대장이 있으면 금액 차감 없이 티켓을 줌
     * 초대장이 없을 떄 : audience 의 금액을 차감하여 티켓을 줌
     */
    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);
        }
    }
}

문제점

위 코드는 매우 많은 문제점을 가지고 있지만 그 중 제가 생각하기에 가장 부적절하다고 생각하는 것을 꼽자면 다음과 같습니다.

1. 낮은 자율성

문제는 관람객과 판매원이 소극장의 통제를 받는 수동적인 존재라는 점이다.

즉 극장을 의미하는 Theater가 관람객이 소지하고 있는 가방을 열어서 직접 초대권 혹은 돈을 가져가고 있으며 티켓 판매원이 가지고 있는 티켓을 직접 제공하고 있다는 것입니다.

이러한 코드는 데이터프로세스가 서로 위치에서 관리하고 있으며 이는 전형적인 절차지향적인 코드의 특징중 하나입니다.

 

그리고 이를 해결하기 위해서는 각 객체들의 자율성을 높이는 방향으로 재설계를 하고 데이터를 직접 가져와서 처리하는 것이 아닌 데이터가 있는 장소에서 프로세스를 통해 처리하는 방향으로 설계해 캡슐화가 가능하게끔 코드를 수정하면 됩니다.

 

2. 높은 의존성

뿐만 아니라 위의 코드는 Theater가 가방, 관람객, 티켓 판매원등 다양한 객체에 의존하고 있는, 높은 의존성을 보이고 있습니다. 객체 지향과 같은 패러다임을 신경쓰지 않더라도 극장이 모든 정보를 알고 있는 것은 분명 문제가 있다고 느껴집니다. 그렇기에 위에서도 말했듯 캡슐화를 통해 결합도는 낮추고 응집도는 높여야합니다.

 

그리고 이를 해결한 코드는 다음과 같습니다.

public class Theater {
    	private TicketSeller ticketSeller;
    
    	public Theater(TicketSeller ticketSeller) {
    		 this.ticketSeller = ticketSeller;
    	}
    
    	public void enter(Audience audience) {
    		 ticketSeller.toSell(audience);   
    	}
}
    
public class TicketSeller {
    	private TicketOffice ticketOffice;
    
    	public TicketSeller(TicketOffice ticketOffice) {
    		 this.ticketOffice = ticketOffice;
    	}
    
     //기존 극장에서 담당하는 enter의 내부 메서드를 toSell 메서드로 작성
    	public void toSell(Audience audience) {
       if(audience.getBag().hasInvitation()) {
         Ticket ticket = ticketOffice.getTicket();
         audience.getBag().setTicket(ticket);
       } else {
         Ticket ticket = ticketOffice.getTicket();
         audience.getBag().minusAmount(ticket.getFee());
         ticketOffice.plusAmount(ticket.getFee());
         audience.getBag().setTicket(ticket);
       }
    	}
}

여기서 TicketSeller의 코드 역시 수정전 코드와 같은 문제점을 지니고 있습니다. 그리고 이러한 문제점은 Bag, Audience라는 클래스를 수정하여 개선할수 있습니다.

 

아래는 수정후의 UML입니다.

개인적인 생각

오브젝트라는 책의 첫장인만큼 책을 관통하는 주제였다고 생각합니다. 그렇기에 기존의 절차지향프로그랭, 객체지향 프로그래밍의 차이점 그리고 객체지향적으로 작성한 코드는 무엇인지 코드로 보여주었다고 생각합니다. 덕분에 기존에 제가 작성한 코드들은 ,책의 표현을 빌리자면, 데이터와 프로세스가 따로 있었음을 깨달았고 향후 이점에 주의하며 코드를 작성할 수 있었습니다. 또한 강의, 그리고 다른 사람의 코드를 보며 어렴풋이 느끼던 것을 문자로 명확하게 정리를 해주는 느낌이였기에 몰입하며 책을 읽을수 있었습니다.

' > 오브젝트 (완)' 카테고리의 다른 글

06 메시지와 인터페이스  (1) 2024.01.23
5장 책임 할당하기  (0) 2024.01.17
4장 설계 품질과 트레이드오프  (0) 2024.01.16
3장 역할, 책임, 협력  (1) 2024.01.15
2장 객체 지향 프로그래밍  (0) 2024.01.11