-
Notifications
You must be signed in to change notification settings - Fork 7
[4주차] ejy #28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The head ref may contain hidden characters: "4\uC8FC\uCC28"
[4주차] ejy #28
Changes from all commits
56b8699
8aba458
d20587a
b28de8f
4fdaadc
ac5f51a
5fd4a44
c66cdf2
dd8f6c7
e66fea4
77ceba8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| # [Java] VO(Value Object) | ||
| ## 1. VO(Value Object)란 | ||
| VO(Value Object)란 말 그대로 값 객체라는 의미를 가지고 있다. 즉, 데이터를 담는 객체이다. | ||
| VO는 데이터베이스에서 한 테이블에 대한 컬럼들과 매칭하여 사용하는 것으로 많이 사용된다. | ||
| VO의 핵심 역할은 **equals()** 와 **hashcode()** 를 오버라이딩 하는 것이다. 즉, VO 내부에 선언된 속성(필드)의 모든 값들이 VO 객체마다 값이 같아야 같은 객체라고 판별한다. | ||
|
|
||
| ## 2. Value Object 기본 특성 | ||
| **Value Object**에는 기본 특성이 있다. | ||
| > 1. Immutability(불변성) - 수정자(setter)가 없음 | ||
| > 2. Value Equality(값 동등성) - 내부 값 동등성 검사 | ||
| > 3. Self Validation(자가 유효성 검사) - 생성자에서 validate | ||
|
|
||
| ### 2-1. Immutability(불변성) - 수정자(Setter)가 없음 | ||
| Value Object는 **불변**이다. | ||
|
|
||
| 불변이라는 뜻은 한번 생성되면 이후 내부 값을 바꿀 수 없음을 의미한다. 즉 **수정자(Setter)를 허용하지 않는다**는 말이다. | ||
|
|
||
| 쉽게 말하면, 생성자에게 하나 혹은 그 이상의 파라미터가 주입돼서 객체가 만들어지면, 돌아갈 수 없음을 의미한다. 해당 객체는 **GC(Garbage Collector)** 에 의해 폐기될 때까지 동일함을 보장한다. | ||
|
|
||
| - Hassle-free Sharing(번거로움없는 공유) | ||
| Value Object는 코드의 다른 부분에서 수정되지 않기 때문에 **Reference(참조)로 공유**할 수 있다. 이는 side effect를 피하기 위해 사용되는 코드의 복잡성과 부하를 극적으로 감소시키며, 멀티스레드 환경에서 그 이점이 뚜렷해진다. | ||
| - Improved Semantics(향상된 의미) | ||
| 불변성을 **"무의미한 생성자(Getter)를 Value Object에 추가하지 않는다."**라는 규칙과 결합해야 한다. 초기 클래스에는 생성자와 private 접근 지정자인 속성만 있어야 한다. | ||
|
|
||
| > ### Value Object를 조작하는 방법 | ||
| > - 생성자 또는 정적 메소드를 통해 새 인스턴스 만들기 | ||
| > - 현재 객체에서 다른 객체 생성하기 | ||
| > - 내부 데이터를 추출해 다른 유형으로 변환하기 | ||
| > - 정적 팩토리 메소드 패턴을 활용해 생성하기(생성자를 private하게 바꿈) | ||
|
|
||
| 위와 같은 방법은 Value Object를 명확하게 해준다. | ||
| ```java | ||
| final class ComplexNumber { | ||
| private float realPart; | ||
| private float complexPart; | ||
|
|
||
| // 정적 메소드를 통해 새 인스턴스 만들기 | ||
| public static ComplexNumber zero() { | ||
| return new ComplexNumber(0, 0); | ||
| } | ||
|
|
||
| // 생성자를 통해 새 인스턴스를 만들기 | ||
| private ComplexNumber(float realPart, float complexPart) { | ||
| this.realPart = realPart; | ||
| this.complexPart = complexPart; | ||
| } | ||
|
|
||
| // 정적 팩토리 메소드 패턴을 활용하여 생성하기 (생성자를 private하게 바꿈) | ||
| public static ComplexNumber of(float realPart, float complexPart) { | ||
| return new ComplexNumber(realPart, complexPart); | ||
| } | ||
|
|
||
| // 현재 객체에서 다른 객체를 생성하기 | ||
| public ComplexNumber add(ComplexNumber anotherComplexNumber) { | ||
| return new ComplexNumber( | ||
| realPart + anotherComplexNumber.realPart, | ||
| complexPart + anotherComplexNumber.complexPart | ||
| ); | ||
| } | ||
|
|
||
| // 내부 데이터를 추출하여 다른 유형으로 변환하기 | ||
| public String toString() { | ||
| return String.format("%f + %f i", realPart, complexPart); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ### 2-2. Value Equality(값 동등성) - 내부 값 동등성 검사 | ||
| Value Object는 내부 값이 모둗 각각 동일한지 확인하여 동등성을 테스트할 수 있다. | ||
|
|
||
| > ### 동일성 vs 동등성 | ||
| > **동일성**은 객체가 완전히 같은지 판단할 수 있는 성질이고, **동등성**은 객체가 같은 정보를 가지고 있는지 판단할 수 있는 성질이다. | ||
| > 동일성은 ```==```로 **주소값**을 비교하고, 동등성은 ```equals()```로 **내용**을 비교한다. | ||
|
|
||
| ### 2-3. Self Validation(자가 유효성 검사) - 생성자에서 validate | ||
| Value Object는 context에서 유효한 값만 허용한다. 이는 유효하지 않은 값으로 Value Object를 만들 수 없음을 의미한다. | ||
|
|
||
| 생성자가 주입될 때 값의 유효성을 확인해야 한다. 유효하지 않으면 의미있는 에러를 표출한다. 이는 객체의 인스턴스에 더이상 if가 없음을 의미한다. **모든 유효성 검사는 생성 시간**에 이루어진다. | ||
|
|
||
| ## 3. 정리 | ||
| 객체를 Value Object로 만들기 위한 체크 리스트 | ||
| - 불변하며 수정자(Setter)가 없다 | ||
| - 도메인의 의미론을 반영한다 | ||
| - 런타임동안 정보의 흐름과 변환 방법을 보여준다 | ||
| - default나 쓸모없는 Getter 메소드가 없다 | ||
| - private 속성을 가지며 다른 Value Object와 비교할 수 있다 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| # [Java] 객체 지향 | ||
| ## 1. 객체 지향이란 | ||
| 객체지향의 목표는 실세계를 모방하는 것이 아닌 새로운 세계를 창조하는 것이다. | ||
|
|
||
| 객체를 스스로 생각하고 스스로 결정하는 현실 세계의 생명체에 비유하는 것은 상태와 행위를 **'캡슐화'** 하는 소프트웨어 객체의 **'자율성'** 을 설명하는 데 효과적이다. 현실 세계의 사람들이 암묵적인 약속과 명시적인 계약을 기반으로 목표를 달성해 나가는 과정은 **'메시지'** 를 주고받으며 공동의 목표를 달성하기 위해 **'협력'** 하는 객체들의 관계를 설명하는 데 적합하다. | ||
|
|
||
| 객체지향이란 | ||
| - 시스템을 상호작용하는 자율적인 객체들의 공동체로 바라보고 객체를 이용해 시스템을 분할하는 방법이다. | ||
| - 자율적인 객체란 상태와 행위를 함께 지니며 스스로 자기 자신을 책임지는 객체를 의미한다. | ||
| - 객체는 시스템의 행위를 구현하기 위해 다른 객체와 협력한다. 각 객체는 협력 내에서 정해진 역할을 수행하며 역할을 관련된 책임의 집합이다. | ||
jeongyuneo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| - 객체는 다른 객체와 협력하기 위해 메시지를 전송하고, 메시지를 수신한 객체는 메시지를 처리하는 데 적합한 메소드를 자율적으로 선택한다. | ||
|
|
||
| ## 2. 객체 지향의 이해 | ||
| ### 2-1. 역할 | ||
| 역할은 관련성 높은 책임의 집합이다. 객체의 역할은 사람의 역할과 유사하게 다음과 같은 특징을 가진다. | ||
| - 여러 객체가 동일한 역할을 수해할 수 있다. | ||
| - 역할은 대체 가능성을 의미한다. | ||
| - 각 객체는 책임을 수행하는 방법을 자율적으로 선택할 수 있다. | ||
| - 하나의 객체가 동시에 여러 역할을 수행할 수 있다. | ||
|
|
||
| 역할은 협력 내에서 다른 객체로 대체할 수 있음을 나타내는 일종의 표식이다. 협력 안에서 역할은 "이 자리는 해당 역할을 수행할 수 있는 어떤 객체라도 대신할 수 있습니다."라고 말하는 것과 같다. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 다형성을 풀어쓴 말 |
||
|
|
||
| 역할을 대체하기 위해서는 각 역할이 수신할 수 있는 메시지를 동일한 방식으로 이해해야 한다. | ||
|
|
||
| 역할은 객체지향 설계의 **단순성**, **유연성**, **재사용성**을 뒷받침하는 핵심 개념이다. | ||
|
|
||
| 역할의 대체 가능성은 행위 호환성을 의미하고, 행위 호환성은 동일한 책임의 수행을 의미한다. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 행위라는 말이 어려울수 있으니 속성, 행위는 상태, 행동으로 쭉 표현해도 좋을듯! |
||
|
|
||
| ### 2-2. 책임 | ||
| 책임이란 객체가 어떤 행동을 하라고 다른 객체로부터 요청을 수신했을 때 요청을 처리하기 위해 객체가 수행하는 행동 즉, 메시지를 수신받았을 때 그 메시지의 요청을 처리하기 위해 수행하는 행동이다. | ||
|
|
||
| 객체의 책임은 크게 두 가지 범주로 분류된다. | ||
| - 하는 것 | ||
| - 객체를 생성하거나 계산을 하는 등의 스스로 하는 것 | ||
| - 다른 객체의 행동을 시작시키는 것 | ||
| - 다른 객체의 활동을 제어하고 조절하는 것 | ||
| - 아는 것 | ||
| - 개인적인 정보에 대해 아는 것 | ||
| - 관련된 객체에 대해 아는 것 | ||
| - 자신이 유도하거나 계산할 수 있는 것에 대해 아는 것 | ||
|
Comment on lines
+32
to
+40
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. calculator에서 하는 것과 아는것을 한번 분리해보는게 어때요?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 그게 예제가 되겠네요. |
||
|
|
||
| 메시지는 객체로 하여금 자신의 책임, 즉 행동을 수행하게 만드는 유일한 방법이다. 메시지를 처리할 수 있다는 것은 객체가 해당 메시지에 해당하는 행동을 수행할 책임이 있다는 것을 의미한다. 따라서 메시지의 개념은 책임의 개념과 연결된다. | ||
|
|
||
| ### 2-3. 협력 | ||
| 객체의 세계에서는 협력이라는 문맥이 객체의 행동 방식을 결정한다. 중요한 것은 개별 객체가 아니라 객체들 사이에 이루어지는 협력이다. | ||
|
|
||
jeongyuneo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| 객체가 다른 객체에게 주어진 책임을 수행하도록 요청을 보내는 것을 **메시지** 전송이라고 한다. 따라서 **두 객체 간의 협력은 메시지를 통해 이루어진다.** | ||
|
|
||
| 객체 지향 설계는 협력에 참여하기 위해 어떤 객체가 어떤 책임을 수행해야 하고 어떤 객체로부터 메시지를 수신할 것인지를 결정하는 것으로부터 시작된다. 어떤 클래스가 필요하고 어떤 메소드를 포함해야 하는지를 결정하는 것은 책임과 메시지에 대한 대략적인 윤곽을 잡은 후에 시작해도 늦지 않다. | ||
|
|
||
| ## 3. 객체 지향 프로그래밍의 특징 | ||
| ### 3-1. 추상화(Abstraction) | ||
| - 객체들의 공통적인 특징(기능, 속성)을 도출하는 것 | ||
| - 객체 지향적 관점에서는 클래스를 정의하는 것을 추상화라고 할 수 있다. | ||
| (클래스가 없는 객체 지향 언어도 존재 ex. JavaScript) | ||
|
|
||
| ### 3-2. 캡슐화(Encapsulation) | ||
| - 실제로 구현되는 부분을 외부에 드러나지 않도록 하여 정보를 은닉할 수 있다. | ||
| - 객체가 독립적으로 역할을 할 수 있도록 데이터와 기능을 하나로 묶어 관리하는 것 | ||
| - 코드가 묶여있어서 오류가 없어 편리하다. | ||
| - 데이터를 보이지 않고 외부와 상호작용을 할 때는 메소드를 이용하여 통신을 한다. 보통 라이브러리로 만들어서 업그레이드해 사용할 수 있다. | ||
jeongyuneo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ### 3-3. 상속성(Inheritance) | ||
| - 하나의 클래스가 가진 특징(함수, 데이터)을 다른 클래스가 그대로 물려받는 것 | ||
| - 이미 작성된 클래스를 받아서 새로운 클래스를 생성하는 것 | ||
| - 기존 코드를 재활용해서 사용함으로써 객체 지향 방법의 중요한 기능 중 하나에 속한다. | ||
|
|
||
| ### 3-4. 다형성(Polymorphism) | ||
| - 약간 다른 방법으로 동작하는 함수를 동일한 이름으로 호출하는 것 | ||
| - 동일한 명령의 해석을 연결된 객체에 의존하는 것 | ||
| - 오버라이딩(Overriding), 오버로딩(Overloading) | ||
| - 오버라이딩(Overriding) : 부모 클래스의 메소드와 같은 이름을 사용하며 매개변수도 같되, 내부 소스를 재정의하는 것 | ||
| - 오버로딩(Overloading) : 같은 이름의 함수를 여러 개 정의한 후 매개변수를 다르게 하여 같은 이름을 경우에 따라 호출하여 사용하는 것 | ||
| - 다형성은 메시지 수신자의 종류를 캡슐화한다. | ||
|
|
||
| ## 4. 정리 | ||
| 객체 지향의 기본 개념은 책임을 수행하는 자율적인 객체들의 협력을 통해 애플리케이션을 구축하는 것이다. 객체지향의 세계에서 객체들이 서로 협력하기 위해 사용할 수 있는 유일한 방법은 **메시지**를 전송하는 것이다. | ||
|
|
||
| **<span style="color:red">객체지향 애플리케이션의 중심 사상은 연쇄적으로 메시지를 전송하고 수신하는 객체들 사이의 협력 관계를 기반으로 사용자에게 유용한 기능을 제공하는 것이다.</span>** | ||
|
|
||
| 클래스 기반의 객체 지향 언어를 사용하는 대부분의 사람들은 객체 지향 애플리케이션을 클래스의 집합으로 생각한다. 프로그래머 입장에서 클래스는 실제 볼 수 있고 수정할 수 있는 구체적인 존재다. 그러나 클래스는 단지 동적인 객체들의 특성과 행위를 정적인 텍스트로 표현하기 위해 사용할 수 있는 추상화 도구일 뿐이다. 중요한 것은 클래스가 아니라 **객체**다. 클래스를 정의하는 것이 먼저가 아니라 객체들의 속성과 행위를 식별하는 것이 먼저다. **<span style="color:blue">클래스는 객체의 속성과 행위를 담는 틀일 뿐이다.</span>** | ||
|
|
||
| 객체 지향 설계의 중심에는 메시지가 위치한다. 객체가 메시지를 선택하는 것이 아니라 메시지가 객체를 선택하게 된다. 메시지가 객체를 선택하게 만드려면 메시지를 중심으로 협력을 설계해야 한다. | ||
|
|
||
| 책임-주도 설계란 책임을 찾고 책임을 수행할 적절한 객체를 찾아 책임을 할당하는 방식으로 협력을 설계하는 방법을 말한다. | ||
| 책임-주도 설계의 핵심은 어떤 행위가 필요한지를 먼저 결정한 후에 이 행위를 수행할 객체를 결정하는 것이다. 즉, '어떻게'가 아닌 '무엇을'을 먼저 생각하는 것이다. | ||
| 이 과정을 흔히 What/Who 사이클이라고 한다. | ||
|
|
||
| > 결론적으로 협력이라는 문맥 안에서 필요한 메시지를 먼저 결정한 후에 메시지를 수신하기에 적합한 객체를 선택한다. 그리고 수신된 메시지가 객체의 책임을 결정한다. | ||
|
|
||
| 협력이라는 문맥 안에서 객체의 책임을 결정하는 것은 메시지다. 책임이 먼저 오고 객체가 책임을 따른다. 결과적으로 시스템이 수행해야 하는 전체 행위는 협력하는 객체들의 책임으로 분배된다. | ||
|
|
||
| 객체가 자신이 수신할 메시지를 결정하게 하지 말고 메시지가 협력에 필요한 객체를 발견하게 해야 한다. | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이는 프로그래밍 과제에서 확인해볼 수 있겠네요.