오브젝트 독서회 6회차 - 6장 메시지와 인터페이스

엄청 오랜만에 정리해서 올리네요.

6회때는 @vincent @freebear 님께서 참석해주셨습니다. 다들 바쁘셔서 참석을 못하셨습니다.

6회차 때는 6챕터와 7챕터를 함께했습니다.

이번에는 6챕터만 올리고 7챕터는 내일 올리도록 하겠습니다.


P175

클래스라는 구현 도구에 지나치게 집착하면 경직되고 유연하지 못한 설계에 이를 확률이 높아진다.

@vincent

여기서 중요한 것은 책임이 객체가 수신할 수 있는 메시지의 기반이 된다는 것이다.

@vincent

클래스 사이의 정적인 관계에서 메시지 사이의 동적인 흐름으로 초점을 전환하는 것은 미숙함을 벗어나 숙련된 객체지향 설계자로 성장하기 위한 첫걸음이다. 애플리케이션은 클래스로 구성되지만 메시지를 통해 정의된다는 사실을 기억하라[Metz12].

@vincent

객체가 수신하는 메시지들이 객체의 퍼블릭 인터페이스를 구성한다.

@vincent @freebear

유연하고 재사용 가능한 퍼블릭 인터페이스를 만드는 데 도움이 되는 설계 원칙과 기법을 익히고 적용해야 한다.

@freebear

P176

협력은 어떤 객체가 다른 객체에게 무언가를 요청할 때 시작된다[Wirfs-Brock03]. 메시지는 객체 사이의 협력을 가능하게 하는 매개체다.

@freebear

P177

메시지는 오퍼레이션명(operation name)인자(argument) 로 구성되며 메시지 전송은 여기에 메시지 수신자를 추가한 것이다[Wirfs-Brock90]. 따라서 메시지 전송은 메시지 수신자, 오퍼레이션명, 인자의 조합이다.

@vincent

P178

이처럼 메시지를 수신했을 때 실제로 실행되는 함수 또는 프로시저를 메서드라고 부른다.

@vincent @freebear

반면 객체는 메시지와 메서드라는 두 가지 서로 다른 개념을 실행 시점에 연결해야 하기 때문에 컴파일 시점과 실행 시점의 의미가 달라질 수 있다.

@vincent

P179

실행 시점에 메시지와 메서드를 바인딩하는 메커니즘은 두 객체 사이의 결합도를 낮춤으로써 유연하고 확장 가능한 코드를 작성할 수 있게 만든다.

@vincent

이처럼 객체가 의사소통을 위해 외부에 공개하는 메시지의 집합을 퍼블릭 인터페이스라고 부른다.

@vincent

프로그래밍 언어의 관점에서 퍼블릭 인터페이스에 포함된 메시지를 오퍼레이션(operation)이라고 부른다. 오퍼레이션은 수행 가능한 어떤 행동에 대한 추상화다.

@vincent @freebear

P180

UML 용어로 말하자면, 인터페이스의 각 요소는 오퍼레이션이다. 오퍼레이션은 구현이 아닌 추상화다.

@vincent

오퍼레이션(또는 메서드)의 이름과 파라미터 목록을 합쳐 시그니처(signature) 라고 부른다. 오퍼레이션은 실행 코드 없이 시그니처만을 정의한 것이다.

@vincent

하지만 다형성의 축복을 받기 위해서는 하나의 오퍼레이션에 대해 다양한 메서드를 구현해야만 한다.

@freebear

P181

중요한 것은 객체가 수신할 수 있는 메시지가 객체의 퍼블릭 인터페이스와 그 안에 포함될 오퍼레이션을 결정한다는 것이다. 객체의 퍼블릭 인터페이스가 객체의 품질을 결정하기 때문에 결국 메시지가 객체의 품질을 결정한다고 할 수 있다.

@freebear

최소한의 인터페이스는 꼭 필요한 오퍼레이션만을 인터페이스에 포함한다.

@vincent

P183

이처럼 협력하는 객체의 내부 구조에 대한 결합으로 인해 발생하는 설계 문제를 해결하기 위해 제안된 원칙이 바로 디미터 법칙(Law of Demeter) 이다. 디미터 법칙을 간단하게 요약하면 객체의 내부 구조에 강하게 결합되지 않도록 협력 경로를 제한하라는 것이다. 디미터 법칙은 “낯선 자에게 말하지 말라(dont’t talk to strangers)[Larman04]” 또는 "오직 인접한 이웃하고만 말하라(only talk to your immediate neighbors)[Metz12]"로 요약할 수 있다. 자바나 C#과 같이 '도트(.)'를 이용해 메시지 전송을 표현하는 언어에서는 "오직 하나의 도트만 사용하라(use only one dot)[Metz12]"라는 말로 요약되기도 한다.

@vincent @freebear

P184

위 설명이 이해하기 어렵다면 클래스 내부의 메서드가 아래 조건을 만족하는 인스턴스에만 메시지를 전송하도록 프로그래밍해야 한다라고 이해하도 무방하다[Larman 2004].

  • this 객체
  • 메서드의 매개변수
  • this의 속성
  • this의 속성인 컬렉션의 요소
  • 메서드 내에서 생성된 지역 객체

@ vincent

P185

디미터 법칙을 따르면 부끄럼타는 코드(shy code) 를 작성할 수 있다[Hunt99]. 부끄럼타는 코드란 불필요한 어떤 것도 다른 객체에게 보여주지 않으며, 다른 객체의 구현에 의존하지 않는 코드를 말한다. 디미터 법ㅍ칙을 따르는 코드는 메시지 수신자의 내부 구조가 전송자에게 노출되지 않으며, 메시지 전송자는 수신자의 내부 구현에 결합되지 않는다. 따라서 클라이언트와 서버 사이에 낮은 결합도를 유지할 수 있다.

@vincent @freebear

디미터 법칙은 캡슐화를 다른 관점에서 표현한 것이다. 디미터 법칙이 가치 있는 이유는 클래스를 캡슐화하기 위해 따라야하는 구체적인 지침을 제공하기 때문이다.

@vincent

다음은 디미터 법칙을 위반하는 코드의 전형적인 모습을 표현한 것이다.

screening.getMovie().getDiscountConditions();

메시지 전송자가 수신자의 내부 구조에 대해 물어보고 반환받은 요소에 대해 연쇄적으로 메시지를 전송한다. 흔히 이와 같은 코드를 기차 충돌(train wreck) 이라고 부르는데 여러 대의 기차가 한 줄로 늘어서 충돌한 것처럼 보이기 때문이다.[Martin08].

@vincent

P186

디미터 법칙을 따르도록 코드를 개선하면 메시지 전송자는 더 이상 메시지 수신자의 내부 구조에 관해 묻지 않게 된다. 단지 자신이 원하는 것이 무엇인지를 명시하고 단순히 수행하도록 요청한다.

screening.calculateFee(audienceCount);

@vincent @freebear

디미터 법칙은 훌륭한 메시지는 객체의 상태에 관해 묻지 말고 원하는 것을 시켜야 한다는 사실을 강조한다. 묻지 말고 시켜라(Tell, Don’t Ask) 는 이런 스타일의 메시지 작성을 장려하는 원칙을 가리키는 용어다.

@vincent

P187

협력을 설계하고 객체가 수신할 메시지를 결정하는 매 순간 묻지 말고 시켜라 원칙과 디미터 법칙을 머릿속에 떠올리는 것은 퍼블릭 인터페이스의 품질을 향상시킬 수 있는 좋은 습관이다.

@freebear

인터페이스는 객체가 어떻게 하는지가 아니라 무엇을 하는지를 서술해야 한다.

@freebear

P190

그러므로 수행 방법에 관해서는 언급하지 말고 결과와 목적만을 포함하도록 클래스와 오퍼레이션의 이름을 부여하라.

@vincent

P191

객체에게 묻지 말고 시키되 구현 방법이 아닌 클라이언트의 의도를 드러내야 한다. 이것이 이해하기 쉽고 유연한 동시에 협력적인 객체를 만드는 가장 기본적인 요구사항이다.

@freebear

P192

근본적으로 디미터 법칙을 위반하는 설계는 인터페이스와 구현의 분리 원칙 을 위반한다.

@vincent

P196

지금까지 살펴본 것처럼 디미터 법칙과 묻지 말고 시켜라 스타일을 따르면 자연스럽게 자율적인 객체로 구성된 유연한 협력을 얻게 된다.

@vincent

따라서 클라이언트의 의도가 분명하게 드러나도록 객체의 퍼블릭 인터페이스를 개선해야 한다.

@freebear

P197

오퍼레이션의 이름은 협력이라는 문맥을 반영해야 한다. 오퍼레이션은 클라이언트가 객체에게 무엇을 원하는지를 표현해야 한다. 다시 말해 객체 자신이 아닌 클라이언트의 의도를 표현하는 이름을 가져야 한다.

@vincent

우리는 결합도가 낮으면서도 의도를 명확히 드러내는 간결한 협력을 원한다. 디미터 법칙과 묻지 말고 시켜라 스타일, 의도를 드러내는 인터페이스가 우리를 도울 것이다.

@freebear

P198

잊지 말아야 하는 사실은 설계가 트레이드오프의 산물이라는 것이다. 설계를 적절하게 트레이드오프 할 수 있는 능력이 숙련자와 초보자를 구분하는 가장 중요한 기준이라고 할 수 있다. 초보자는 원칙을 맹목적으로 추종한다. 심지어 적용하려는 원칙들이 서로 충돌하는 경우에도 원칙에 정당성을 부여하고 억지로 끼워 맞추려고 노력한다.

@vincent

원칙이 현재 상황에 부적합하다고 판단된다면 과감하게 원칙을 무시하라.

@freebear

P199

하나 이상의 도트(.)를 사용하는 모든 케이스가 디미터 법칙 위반인 것은 아니다. 기차 충돌처럼 보이는 코드라도 객체의 내부 구현에 대한 어떤 정보도 외부로 노출하지 않는다면 그것은 디미터 법칙을 준수한 것이다.

@vincent

P202

로버트 마틴은 <클린코드>[Martin08]에서 디미터 법칙의 위반 여부는 묻는 대상이 객체인지, 자료 구조인지에 달려있다고 설명한다. 객체는 내부 구조를 숨겨야 하므로 디미터 법칙을 따르는 것이 좋지만 자료 구조라면 당연히 내부를 노출해야 하므로 디미터 법칙을 적용할 필요가 없다.

@vincent

명령(Command)쿼리(Query) 는 객체의 인터페이스 측면에서 프로시저와 함수를 부르는 또 다른 이름이다. 객체의 상태를 수정하는 오퍼레이션을 명령이라고 부르고 객체와 관련된 정보를 반환하는 오퍼레이션을 쿼리라고 부른다. 따라서 개념적으로 명령은 프로시저와 동일하고 쿼리는 함수와 동일하다.

@vincent

P203

어떤 오퍼레이션도 명령인 동시에 쿼리여서는 안 된다. 따라서 명령과 쿼리를 분리하기 위해서는 다음의 두 가지 규칙을 준수해야 한다.

  • 객체의 상태를 변경하는 명령은 반환값을 가질 수 없다.
  • 객체의 정보를 반환하는 쿼리는 상태를 변경할 수 없다.

@vincent

명령-쿼리 분리 원칙을 한 문장으로 표현하면 "질문이 답변을 수정해서는 안 된다"는 것이다. 명령은 상태를 변경할 수 있지만 상태를 반환해서는 안 된다. 쿼리는 객체의 상태를 반환할 수 있지만 상태를 변경해서는 안 된다.

@freebear

P209

안타깝게도 대부분의 사감들은 isStatisfied 메서드가 부수효과를 가질 것이라고 예상하지 못할 것이다. 사실 isSatisfied 메서드가 처음 구현됐을 때는 그 안에서 reschedule 메서드를 호출하는 부분이 빠져 있었다. 기능을 추가하는 과정에서 누군가 Event가 RecurringSchedule의 조건에 맞지 않을 경우 Event의 상태를 수정해야 한다는 요구사항을 추가했고, 프로그래머는 별다른 생각 없이 기존에 있던 isSatisfied 메서드에 reschedule 메서드를 호출하는 코드를 추가해 버린 것이다.

@vincent

명령과 쿼리를 뒤섞으면 실행 결과를 예측하기가 어려워 질 수 있다.

@vincent @freebear

P210

그 결과, 코드는 예측 가능하고 이해하기 쉬우며 디버깅이 용이한 동시에 유지보수가 수월해질 것이다.

@freebear

P211

쿼리는 객체의 상태를 변경하지 않기 때문에 몇 번이고 반복적으로 호출하더라도 상관이 없다.

@vincent

수학에서 함수는 입력이 동일하면 결과 역시 항상 동일해야 하기 때문이다.

@vincent

컴퓨터의 세계와 수학의 세계를 나누는 가장 큰 특징은 부수효과(side effect) 의 존재 유무다.

@vincent

P212

부수효과를 이야기할 때 빠질 수 없는 것이 바로 참조 투명성[Meyer00] 이다. 참조 투명성이란 "어떤 표현식 e가 있을 때 e의 값으로 e가 나타나는 모든 위치를 교체하더라도 결과가 달라지지 않는 특성"을 의미한다.

수학은 참조 투명성을 엄격하게 준수하는 가장 유명한 체계다.

@vincent

P214

따라서 함수형 프로그래밍에서는 참조 투명성의 장점을 극대화할 수 있으며 명령형 프로그래밍에 비해 프로그램의 실행 결과를 이해하고 예측하기가 더 쉽다.

@vincent

P215

버트란드 마이어는 이런 문제를 해결하기 위해 계약에 의한 설계(Design By Contract) 개념을 제안했다. 계약에 의한 설계는 협력을 위해 클라이언트와 서버가 준수해야 하는 제약을 코드 상에 명시적으로 표현하고 강제할 수 있는 방법이다.

@vincent

7개의 좋아요

현재는 이미 12챕터까지 독서회를 마친 상태이기 때문에 6챕터만의 학습 당시의 생생한 독후감은 어렵습니다. 기억도 희미하네요 거의 2달 전 것이라…

기억이 나는 것으로는, CQRS 에 대한 개념이 언급된 만큼 OOP의 연장선에 MVVM 뿐아니라 CQRS도 있구나 하는 것이었습니다.

이런 방법론들이 결국 유지보수를 유용하게 하기 위한 방법들로 제시된 것이고 현장에서 인증이 된 것들이다보니 기업에서 서비스가 성장하는 추세라면 이런 기법들을 사용해야할 시점이 올 것이고 그를 위해 OOP를 잘 이해한 팀 빌딩을 해야한다…뭐 그런 말을 했던거 같네요.

이 책의 저자는 1챕터부터 현재 진행된 12챕터까지 계속해서

OOP는 메시지와 책임이 전부이며, 추상화에 대해 의존하라

이 한 줄을 계속해서 주장하고 있습니다. 저도 마치 가스라이팅 당한 것처럼 이제 계속 보다보니 이해가 되는 것처럼 착각?인지 이해가 되고는 있습니다.

결국 돌고돌아 결국 인터페이스…

나중에 소개되겠지만 ‘생성에 대한 책임’ 이 의존성을 강하게 결합하므로 위에 언급된 디미터 법칙으로 시키라고 합니다.

저는 언젠가 강연에서 스타크래프트 유즈맵인 생산과 컨트롤 이라고 표현했었는데요. 이것이 관통하는 하나의 비유가 아닐까 싶네요.

내일 7챕터로 돌아오겠습니다.

7챕터는 좀 쉬어가는 챕터라고 저자가 언급한 만큼 추상화와 연결된 재미있는 비유들이 있었습니다.

6개의 좋아요

이 구절은 제가 관심을 두고 있는 주제와 연결된 듯하여 매우 흥미롭네요.

상속 대신 합성(Composition)을 고려하라

위 말을 한 번쯤은 들어 보셨을 것입니다.
주로 C++ 기반의 객체 지향 진영이나 엔티티 컨텍스트에서 자주 언급되더군요.

개인적인 생각으로는, 객체는 속성의 집합으로 나타나기에, 속성을 집합으로 묶는 것은 정체성의 표현 방식이라고 할 수 있습니다. 상속이 아닌 결합을 채택하면, 그 속성 집합이 대변하는 정체성을 포기하는 것과 같고, 이는 "추상화에 의존하는 설계"를 헤칠 수 있어, 합성과 상속은 대체제 관계가 아니라고 생각합니다.

class Base { }

class Inherited : Base { }
class Composited
{
    public Base Base;
}

var inherited = new Inherited();
var composited = new Composited();

Base base = inherited;
Base base2 = composited; //  에러
Base base3 = composited.Base; // 에러는 아니지만, 디미터 법칙 위배를 유도.

그러나, 저자는 일관적으로 트레이드 오프를 강조하고 있기에, 명확하게 필자도 상속 대신 합성을 고려하면 안된다라고 단언하기에도 애매한 부분이 있네요.

향 후, 필자의 입장을 읽을 수 있는 내용이 이어질 것 같아 더욱 기대됩니다.

계속 응원하며, 다음 글 기대하겠습니다.

4개의 좋아요

뒷부분에 11챕터에 가면 상속에 관한 내용도 자세하게 말하는데, 저자도 @BigSquare 님과 유사하게 말하는 부분이 있습니다. 글만 봐서는 거의 같지 않나(?) 싶습니다…

11챕터 할 때 자세하게 적겠지만 합성을 위주로 사용하라곤 하나, 상속을 사용할 때 상속의 목적을 중복 소스코드 방지가 아닌 추상화의 Layer개념 으로 사용할 경우가 추상화에 의존하는 상속을 사용하는 방법 이라고 했습니다.

저도 처음에 일반 super 클래스를 참조하거나, 추상클래스를 사용할 때 중복 소스코드의 기본구현 방지 용도로 사용했는데 용법으로 접근할 때는 그렇게 시작은 할 수 있겠으나 궁극적인 목적은 super, this에 대해서 pointer형태로 mesage를 던지는 개념이기 때문에 중복소스코드 방지가 아닌 부모, 또는 자신의 객체에게 메세지를 던지라 라는 개념으로 상속을 해석하고 있습니다.

3개의 좋아요

또한 저한테 아주 중요한 사고를 깨우쳐준 개념 또한 있는데,

10챕터에 가면 Mix-In 이라는 개념을 소개하면서

C# 8.0 부터 도입된 Interface에 대한 기본 구현에 대한 내용입니다.

밑 부분은 원래 10, 11 챕터에 가면 해야 할 내용이지만 업데이트 하다가 또 생각이 안 날수도 있고 구현에 대한 이슈업에 된 이상 지금 하는 게 맞을 것 같습니다.


저는 이 기능이 업데이트 되었을 떄 전통 OOP 개념을 해친다고 생각했습니다.

Interface는 메시지이고, 책임을 나타내는데 책임에 대한 기본구현이 생기므로써 책임이 책임이 아니게 되었다고 생각하면서 믹스인 개념을 싫어했고, 호불호에 관련된 내용이라고 생각했습니다.

이 기능이 처음 추가된 것은 Java의 기본구현이라고 생각했으며 이 Interface의 기본 구현이 등장하게 된 이유 중 찾을 수 있었던 것은

Interface에 대해 다중 Layer로 추상화를 해놨더니, 유지보수를 할 때 같은 Interface 를 구현하는 클래스들 끼리 공통 구현에 대한 소스코드 가 중복되는 것이 많아졌다. 전통 인터페이스 개념을 살려서 이런 경우 중복 소스코드 방지를 없에기 위해 클래스를 사용해서 중복소스코드를 줄였더니, OOP는 상속계층이 단일 방향이기에 다중상속이 안되어서 Layer를 오히려 복잡하게 만들었다. 이 경우 Interface에 기본 구현을 사용했더니 이런 부분들이 해결되었다. 다만, 이 경우 Interface에 대한 다이아몬드 상속 이 될 수 있어서 호불호가 발생할 수 있다.

위 글은 제가 언젠가 인터페이스 기본구현에 대해 찾아보면서 읽었던 글을 기억을 되살려서 적었습니다. 그때는 믹스인 이라는 개념을 모를 때 였고, 위 글을 봐쓸 때 공감했고 저는 호불호 중 불호였습니다.

이유는 다이아몬드 상속이 OOP를 해친다고 생각했기 때문이고 다이아몬드 상속은 C++ 때부터 이슈업되었던 것이고 그로 인해 C++는 다중상속이 가능한 만큼, 단일 상속구조로 가져가기 위해 클래스 지향 설계 라는 용어가 따로 언급이 되었을 정도로 C++를 OOP 적으로 사용하려고 했던 시도와 운동이 있던 것으로 알고 있습니다.

하지만 오브젝트 10챕터의 믹스인 개념은 이것을 깨줬고, 저자는 스칼라(Scala)의 Trait 개념을 소개하면서 믹스인을 언급하고 있었습니다.

이 스칼라의 Trait는 Trait에 기본 구현을 정의하여 여러 개의 Trait을 하나의 클래스에 Plug-in 처럼 붙혀서 Class 기능을 확장할 수 있는 개념이었습니다.

여기까지만 보면 스칼라 Trait은 정말 훌륭한 개념이었고 C#에는 이런 개념이 없나? 하고 찾아봤는데 함께 10챕터 독서회를 진행해주셨던 @은딩 님께서 위 MSDN의 C# 믹스인을 찾아주셨습니다.

여기까지 보고나니 갑자기 없었던 벽이 생성되면서 “아 뭐야, Trait이 결국 기본구현 Interface였어?” 하면서 모르고 볼 때는 아름답게 보이다가 실체를 알고 보니 추하게 보였습니다. 없던 선입견이 불러와서 생긴 것이지요.

하지만 좀 더 생각을 해보니까 Class가 아니라 Interface로서 기본 구현을 가졌기 때문에 시사하는 바가 다른 것처럼 느껴졌습니다.

  1. 첫번째로 우선은 저는 OOP를 쓰는 이유가 첫째도 둘째도 셋째도 N째도 유지보수 때문에 사용하는 것인데 믹스인을 사용하면 유지보수가 더욱 뛰어나질텐데 내가 생각하는 OOP와 달라졌다고 무작정 싫어할 이유도 없었다는 것을 깨달았습니다.
    제가 어디가서 패턴을 위한 패턴을 하지 말고 유지보수를 위한 적절한 트레이드 오프를 섞으라고 말하고 다니면서도 스스로 OOP를 위한 OOP를 하려고 했다는 사실을 깨달았습니다.

  2. 두번째로 그것이 class가 아니라 Interface라서 용납이 되었습니다. 저자는 끊임없이 Interface는 메시지이고 책임이며 상속이 아니라 구현이라고 말하고 있습니다. OOP의 원형 자바에서도 extends가 아니라 implements이라고 하는 것처럼요. 즉 믹스인이라고, 기본 구현이 있다고 해서 그것이 상속이 되는 것은 아니라는 것을 깨달았습니다. 인터페이스에 기본 구현이 추가되었다고 해도, 인터페이스는 여전히 메시지이고, 책임이었습니다.

구현에 초점을 맞추는 것이 아니라 우리가 공부하는 OOP가 추상적인 개념을 공부하듯 그 본래 의미를 안다면 구현은 더 이상 중요해지지 않다는 것을 깨달았습니다.


11챕터에 쓸 독후감을 미리 쓴 듯 한데, 더 추가할 수도 있겠지만 이것으로 개인 독후감은 링크로 끝낼거같네요…ㅎ

5개의 좋아요

우리 나라에서 유독 널리 퍼진 오해 같습니다.
아마 자바를 통해 OOP가 본격적으로 소개되었기 때문인 것 같습니다.

최초의 순수(Pure) 객체 지향 언어는 SmallTalk 입니다. (그러나, 최초로 OOP의 개념을 도입한 언어는 아닙니다)

어떤 이는 C++, Java, C#이 OOP를 오염시켰다고도 표현하더군요.

현재 독서회에서 읽고 있는 책이 강조하는 "메시지를 통한 객체 간 협업"은 SmallTalk 의 창시자 Allen Kay 가 정립한 것입니다. 추상화, 상속, 다형성은 그로 인한 부차적인 특징일 뿐인데, 위의 언어들이 부차적인 면을 너무 강조하여 본질 보다 중요하게 보이도록 만들었다는 이유에서입니다.

부차적인 면이 강조되면 OOP 스타일이 명확하지 않게 되고, 그로 인해 OOP를 사용해도 유지보수성이 수시로 나빠지는 것이죠.

우리가 C# 이라는 객체 지향 언어를 사용해도, 여전히 해소되지 않는 유지보수성에 대한 목마름이 이러한 책을 찾게 만드는 것은 아닐런지요.

3개의 좋아요

그랬군요. 교정해주셔서 감사합니다. 이 책에 간간히 SmallTalk 에 관해 언급되는데 그게 OOP 언어라서 언급이 되었던 것이군요. Allen Kay 라는 분은 언급되셨었는지 기억이 안나네요. 이전 회차들의 독서회 때는 인용구마다 누가 한 말인지 표시를 안했었는데 요즘은 표기하고 있어서 요즘 조금씩 보이고 있습니다.

제가 적은 인용구에 [Hunt99] 이런 게 그런 것인데, 책을 보다가 인용구가 또다시 등장하면 유심히 봐야겠습니다.

저는 한 가지 조금 다른 생각은 유지보수라는 관점이 가장 중요하다는 입장입니다.

함수형으로 하던 OOP로 하던 아니면 새로운 개발 메타 프로그래밍이 나와서 그게 효율적이라면 그게 좋다고 생각합니다. 아까 위에 적은 문장에도 OOP를 위한 OOP를 할뻔했다가 다시 제 원래 관점으로 돌아온 것입니다. 결국 기업에서 보는 건 서비스가 잘 도는지, 코드의 수정과 배포가 빠른지 인데 이런 것들을 찾기 위해 연구되었던 것들이 이론으로 정립된 분야 중 하나가 OOP라고 보는 편입니다.

그래서 기업들마다 회사의 어떤 CTO가, 수석연구원 등이 정립해 놓은 회사 자체의 개발 패턴이 중요하지 않고, 기업 입장에서 대체인력을 구하고, 직원이 다른 사람에게 일을 위임하고 휴가를 가고, 개발자 온보딩의 시간을 줄이려면 시중에 널리 퍼져 있는 대중적인 이론을 습득한 개발자가 필요하다는 생각입니다.

그 중에 가장 널린 게 OOP라고 생각해서 OOP를 좋아하는 것입니다.

C#은 객체 지향언어이긴 하나, 객체지향적이기만 언어가 아니게 된 데는 여러 언어들의 유지보수성이 뛰어나고 인기있는 부분을 받아들였다고 생각하기 때문입니다. 그리고 그런 인기는 OOP를 위한 OOP를 했기 때문이 아니라 그냥 유지보수에 용이해서라는 무척 심플한 원칙이 아닐까 싶습니다.

요즘 보고 있는 크리에이티브 프로그래머 라는 책에도, 그 당시의 사람들이 그것을 인정해줄 때 창의적인 방법이라고 하는 것처럼 언젠가 다시 미래에 순수한 OOP만 지향하는 스타일이 인정받을 수는 있겠지만, 현재는 좋은 것을 여러 사람들이 함께 연구하는 집단지성의 능력으로 장점들이 점점 융합되는 C#이 좋은 것 같습니다.

4개의 좋아요