Skip to content

Latest commit

 

History

History
256 lines (179 loc) · 6.52 KB

1회차.md

File metadata and controls

256 lines (179 loc) · 6.52 KB

합리성 ?

image

간단하게 짜야 유연성을 얻는다.

객체지향 진영에서 유일하게 제시하는 한 가지 방법은 역할모델이다.

역할모델 이외에는 어떠한 도메인을 격리시킬 수 있는 수단을 발견하지 못 했다.


추상화

역할 모델을 이해하려면 추상화에 대한 이해가 필요하다

  • 일반화(Genralization) - modeling, function, algorithm
  • 연관화(Association) - reference, dependence <- 위임 가능
  • 집단화(Aggregation) - group, category

종류

Data Abstration

  • Modeling: 특정 목표에 따라 기억하고 싶은 것만 추린 것
  • Categorization
  • Grouping: 집합

Procedural Abstration

프로시저는 데이터의 처리를 함수에게 양도함을 뜻하는 "고유명사"다.

  • Genralization: 일반화를 잘 사용하면 함수를 여러개 만들 필요가 없음
  • Capsulization: 캡슐화는 보다 추상적인 행위를 표현한다 (정보은닉과는 다름)

OOP Abstration

  • Genralization: 인터페이스나 추상클래스로 일반화
  • Realization: 인터페이스나 추상클래스를 구현
  • Dependency: 인자를 받거나 참조
  • Association: 필드들
  • Directed Association
  • Association
  • Composition

Timing

프로그램이 실행되는 순간이 언제냐

image

자바는 최초로 런타임 로딩을 사용하였다.

그래서 실행이될때 모든 것을 메모리에 적재하지 않고 사용이될떄 클래스로더로 불러온다.

그래서 배포할때 첫 요청들은 느렸군아

파일에 있는 변수들은 VTable 로 관리되다가 실제 실행이 될 떄 가상 메모리 주소를 진짜 메모리 주소로 치환한다.


Pointer of Pointer

데이형은 데이터가 얼마나 길게 가져가야하는지를 나타냄

image

직접 참조는 모든 버그의 원인이다 ....

그래서 참조의 참조를 통해서 사용


Value & Identifier

class ValueType(val name: String) {
  override operator fun equals(n: Any?) = n == name
}

객체를 구분한느 방법은 식별자이다.

식별자는 런타임에 메모리에 적재되어 있던 메모리 주소, 똑같은 객체가 있다고 하더라도 메모리 주소가 틀리니 같은 주소가 아니다.

그러기 때문에 객체인지 값인지에 따라 비교 기준이 다르게 된다.

즉 값 컨텍스트와 객체 컨텍스트는 다르다.

ValueType("abc") == ValueType("abc") // true
ValueType("abc") === ValueType("abc") // false

이론적으로 모든 값들도 객체로 구성이 되어야 진정한 객체지향 프로그래밍이라고 할 수 있다.


Polymorphism (다형성)

  • Subsitution: 대첵가능성 <- 서로 대체 ??
  • Internal identity: 내적동질성 <- 출신지가 더 중요
open class Worker: Runnable {
  override fun run(): println("working")
}

var worker: Runnable = Worker()
println(worker.run()) // workimg

상속은 참조에 참조의 연속이다.


Object (객체)

  • Encapsulation of Functionality 기능을 캡슐화할 수 있어야함

  • Maintenance of State 상태를 관리할 수 있어야함 ex) 은닉

isolataion

격리가 되었는지 확인을 하는 가장 확실한 방법은 다른 파일도 같이 수정이 되었는가 확인


예제

AS-IS

image

TO-BE

image

극장이 ticket office 를 아는 것이 맞지 않을까 ??

예제 코드

class Theater {
  private final List<TicketOffice> ticketOffices = new ArrayList<>;
  private final Long fee;

  /**
  * 다수의 ticketOffice 수용
  */
  public void setTicketOffices(TicketOffice ... ticketOffices) { }
  
  /**
  * 티켓은 극장에서 티켓오피스로 줄 수 밖에 없다.
  * 티켓의 주요 식별자는 극장이다.
  */
  public void setTicket(TicketOffice ticketOffice, Long num) { }
  
  /**
  * 극장이 특정 귀빈에게 초대권을 준다.
  */
  public void setInvitation(Audience audience) { }

  /**
  * 입장을 시켜준다.
  */
  public boolean enter(Audience audience) { //TODO: validate }
}

class Ticket {
    final static public Ticket EMPTY = new Ticket(null); // Null 객체 패턴
    final private Theater theater;
    private boolean isEntered = false;

    public Ticket(Theater theater) {
        this.theater = theater;
    }

    public boolean isValid(Theater theater) {
        if (isEntered || theater != this.theater || this == EMPTY) {
            return false;
        } else {
            isEntered = true;
            return true;
        }
    }
    
    public Long getFee() {
        return theater.getFee();
    }
}

public class Invitation {
    final static public Invitation EMPTY = new Invitation(null);
    final private Theater theater;

    public Invitation(Theater theater) {
        this.theater = theater;
    }
}

/**
 * TicketOffice 는 Theater 를 알 필요가 없다.
 */
class TicketOffice {
    private Long amount;
    private List<Ticket> tickets = new ArrayList<>();

    public TicketOffice(Long amount) {
        this.amount = amount;
    }

    public void addTicket(Ticket ticket) {
        this.tickets.add(ticket);
    }

    public Ticket getTicketWithFee() {
        if (tickets.size() == 0) {
            return Ticket.EMPTY;
        } else {
            Ticket ticket = tickets.remove(0);
            amount += ticket.getFee();
            return ticket;
        }
    }
    
    public Ticket getTicketWithNoFee() {
        if (tickets.size() == 0) {
            return Ticket.EMPTY;
        } else  {
            return tickets.remove(0);
        }
    }
    
    public Long getTicketPrice() {
        if (tickets.size() == 0) {
            return 0L;
        } else {
            return tickets.get(0).getFee(0);
        }
    }
}

class TicketSeller {
    private TicketOffice ticketOffice;

    public TicketSeller(TicketOffice ticketOffice) {
        this.ticketOffice = ticketOffice;
    }
    
    public Ticket getTicket(Audience audience) {}
}

이러한 설계를 TDD 로 할 수 있는 사람은 켄트백 말고는 없다고함 ....