완벽한 설계?

2006/08/03 22:16
실전코드로 배우는 실용주의 디자인 패턴을 읽으면서 공감이 가는 글들을 뽑아서 적어본다.

완벽한 설계란 있을수 없겠지만, 완벽에 가까운 설계일수록 군더더기가 없고 단순한다.


설계에 있어 완벽함이란 더 이상 추가할 것이 없을 때 이루어지는 것이 아니라 더 이상 버릴 것이 없을 때 이루어진다.
- Eric S. Raymond


실전 코드로 배우는 실용주의 디자인 패턴

Allen Holub / 사이텍미디어(희중당)

어쩌어쩌하다가 우연히 블로그에서 아이디/별명 검색UI를 보았다.

아이디와 별명이 다른 필드임에도 불구하고, 아이디 or 별명이라는 인터페이스가 존재를 했다. 그것도 서버쪽 인터페이스가 아니라 일반적으로 많이 사용할 만한 클라이언트쪽 인터페이스였다.

처음에 기획의도는 한방에 편하게 검색하는 것이라고 생각은 들지만, 개발을 할때 개발자는 한번도 생각을 해서 기획자와 협의를 통해서 인터페이스를 바꾸어야 했지 않나 싶다. or관련된 쿼리의 퍼포먼스저하 문제는 공인된(?) 사실중의 하나이다. 실질적으로 이런 조금만 것들이 모여서 어플리케이션의 성능을 저하시킨다.

기획적으로 조금만 UI를 다르게 생각해서 비슷한 효과를 볼수 있는 방법이 있을듯한데, 굳이 or로만 해결할수 있게 화면을 구성한 것은 아쉬운 일이다.

웹에서의 화면 구성은 중요한 이슈중의 하나이다. 기획자가 미쳐 놓치고 간 부분이 있다면, 개발자가 advice를 통해서 불필요한 부하를 일으킬 필요는 없지 않을까?  

개발을 할때도 고민하면서 창의적으로 업무를 수행할 필요가 있겠지만,  기획서, 스토리 보드를 확인할때도 좀더 고민하자.

1. 경직성 : 무엇이든지 하나를 바꿀 때마다 반드시 다른 것도 바꿔야 하며, 그러고 나면 또 다른 것도 바꿔야 하는 변화의 사슬이 끊이지 않기때문에 시스템을 변경하기 힘들다.

2. 부서지기 쉬움 : 시스템에서 한 부분을 변경하면 그것과 전혀 상관없는 다른 부분이 작동을 멈춘다.

3. 부동성 : 시스템을 여러 컴포넌트로 분해해서 다른 시스템에 재사용하기 힘들다.

4. 끈끈함 : 개발환경이 배관용 테이프나 풀로 붙인 것처럼 꽉 달라붙은 상태다.
편집-컴파일-테스트 순환을 한번 도는 시간이 엄청나게 길다.

5. 쓸데없이 복잡함 : 괜히 머리를 굴려서 짠 코드구조가 굉장히 많다. 이것들은 대개 지금 당장 하나도 필요 없지만, 언젠가는 굉장히 유용할지도 모른다고 기대하며 만들었다.

6. 필요없는 반복 : 코드를 작성한 프로그래머 이름이 마치 '복사'와 '붙여넣기' 같다.

7. 붙투명함 : 코드를 만든 의도에 대한 설명을 볼때 그 설명에 '표현이 꼬인다' 라는 말이 잘 어울린다.

Java프로그래머를 위한 UML, 실전에서는 이것만 쓴다.
- 로버트 C.마틴(인사이트)

가장 기본적인 OOP의 원칙이지만, 제대로 하기는 쉽지 않다. 생각없이 코드를 만들어낸 후 내가 짠 소스를 보면서 중복코드와 라인수가 많은 메소드, 수많은 if들을 보면서 고통스러울때가 있다. 다음에는 꼭 그렇게 안해야지 하면서도 아직 내공이 부족하여 실행을 못할 경우가 많다.

최근 디자인 패턴, 코드질에 더 신경을 쓰는 이유는 이제는 노력을 더 해야겠다는 결심을 해서이다.

'중복코드 방지와 개발생산성 증대 및 유지보수를 편하게 한다' 는 대전제 아래 다시 한번 알면서도 제대로 행하지 못한 나의 잘못된 습관들을 refactoring하려고 한다.

객체지향의 기초
추상화 , 캡슐화 , 다형성 , 상속

객체지향의 원칙

  • 바뀌는 부분을 캡슐화한다.
  • 상속보다는 구성을 활용한다.
  • 구현이 아닌 인터페이스에 맞춰서 프로그래밍한다.
  • 서로 상호작용을 하는 객체사이에서는 가능하면 느슨하게 결합하는 디자인을 사용해야 한다.
  • OCP(Open-closed Principle) : 클래스는 확장에 대해서는 열려있어야 하지만, 코드 변경에 대해서는 닫혀 있어야 한다.
  • 추상화된 것에 의존하라. 구상 클래스에 의존하지 않는다.
  • 친한친구들하고만 이야기한다.
  • 먼저 연락하지 마세요. 저희가 연락 드리겠습니다.
  • 클래스를 바꾸는 이유는 한 가지 뿐이어야 한다.

디자인 원칙

  • 애플리케이션에서 달라지는 부분을 찾아내고, 달라지지 않는 부분으로부터 분리시킨다.(인터페이스와 구현부의 분리)
    : 달라지는 부분을 찾아서 나머지 코드에 영향을 주지 않도록 캡슐화합니다. 그러면 코드를 변경하는 과정에서 의도하지 않은 일이 일어나는 것을 줄이면서 시스템의 유연성은 향상시킬 수 있습니다.
  • 서로 상호작용을 하는 객체 사이에서는 가능하면 느슨하게 결합하는 디자인을 사용해야 한다.
  • 추상화된 것에 의존하도록 만들어라. 구상 클래스에 의존하도록 만들지 않도록 한다.
  • 최소 지식의 원칙 : 정말 친한 친구하고만 얘기하라
  • 객체지향 프로그래밍에서는 친구가 하나만 있는 것이 좋습니다.
  • 구현이 아닌 인터페이스에 맞춰서 프로그래밍한다.
    : 객체가 코드에 의해서 고정되지 않도록 , 어떤 상위 형식(supertype)에 맞춰서 프로그래밍함으로써 다형성을 활용해야 한다. 구체적으로 구현된 객체는 실행시에 대입하는 것 -> 상속을 쓸때 떠안게 되는 부담을 전부 떨쳐 버리고도 재사용성의 장점을 그대로 누릴 수 있습니다.

전문용어의 위력

  • 서로 알고 있는 패턴 용어는 정말 막강합니다.
  • 패턴을 이용하면 간단한 단어로 많은 것을 얘기할 수 있습니다.
  • 패턴수준에서 이야기를 하면 디자인에 더 오랫동안 집중할 수 있습니다.
  • 전문용어를 사용하면 개발 팀의 능력을 극대화할 수 있습니다.
  • 전문용어는 신참개발자에게 훌륭한 자극제가 됩니다.

    객체지향 패턴
    스트래티지 패턴(strategy pattern) : 알고리즘군을 정의하고 각각을 캡슐화하여 교환해서 사용할 수 있도록 만든다. 스트래티지를 활용하면 알고리즘을 사용하는 클라이언트와는 독립적으로 알고리즘을 변경할 수가 있다.

    옵저버 패턴(Observer Pattern) : 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고 자동으로 내용이 갱신이 되는 방식으로 일대다(one-to-many) 의존성을 정의합니다.
    ex) java.util.Observable

    데코레이터 패턴(Decorator Pattern) :  객체에 추가 요소를 동적으로 더할 수 있습니다. 데코레이터를 사용하면 서브 클래스를 만드는 경우에 비해 훨씬 유연하게 기능을 확장할 수 있습니다 .
    ex) java.io에 관련된 클래스들

    팩토리 메소드 패턴(Factory Method Pattern) : 팩토리 메소드 패턴에서는 객체를 생성하기 위한 인터페이스를 정의하는데, 어떤 클래스의 인스턴스를 만들지는 서브클래스에서 결정하게 됩니다. 팩토리 메소드 패턴을 이용하면, 클래스의 인스턴스를 만드는 일을 서브클래스에게 맡기는 것

    추상팩토리 패턴(Abstract Factory Pattern) : 추상 팩토리 패턴에서는 인터페이스를 이용하여 서로 연관된, 또는 의존하는 객체를 구상클래스를 지정하지 않고도 생성할 수 있습니다.

    싱글턴 패턴(singleton pattern) : 해당 클래스의 인스턴스가 하나만 만들어지고, 어디서든지 인스턴스에 접근할 수 있도록 하기 위한 패턴입니다.

    커맨드 패턴(Command Pattern) : 커맨드 패턴을 이용하면 요구사항을 객체로 캡슐화 할 수 있으며, 매개변수를 써서 여러가지 다른 요구 사항을 집어 넣을 수도 있습니다. 또한 요청 내역을 큐에 저장하거나 로그로 기록할 수도 있으며, 작업취소 기능도 지원합니다.

    어댑터 패턴(Adapter Pattern) : 한 클래스의 인터페이스를 클라이언트엗서 사용하고자 하는 다른 인터페이스로 변화합니다. 어댑터를 이용하면 인터페이스 호환성 문제때문에 같이 쓸수 없는 클래스들을 연결해서 쓸수가 있습니다.

    퍼사드 패턴(Facade Pattern) : 어떤 시스템의 일련의 인터페이스에 대한 통합된 인터페이스를 제공합니다. 퍼사드에서 고수준 인터페이스를 정의하기때문에 서브시스템을 더 쉽게 사용할 수 있습니다.

    템플릿 메소드 패턴(Template Method Pattern) : 메소드에서 알고리즘의 골격을 정의합니다. 알고리즘의 여러 단계중 일부는 서브클래스에서 구현할 수 있습니다. 템플릿 메소드를 이용하면 알고리즘의 구조는 그대로 유지하면서 서브클래스에서 특정 단계를 재정의할 수 있습니다.
    ex)  알고리즘의 틀을 만들기 위한 패턴

    이터레이터 패턴(Iterator Pattern) : 컬렉션 구현 방법을 노출시키지 않으면서도 그 집합체 안에 들어있는 모든 항목에 접근할 수 있게 해주는 방법을 제공해 줍니다.

    컴포지트 패턴(Composite Pattern) : 객체들을 트리구조로 구성하여 부분과 전체를 나타내는 구조로 만들 수 있습니다. 이 패턴을 이용하면 클라이언트에서 개별 객체와 다른 객체들로 구성된 복합 객체(Composite)를 똑같은 방법으로 다룰수 있습니다.

    • 컴포지트 패턴이 클라이언트가 보기에 투명하게 작동하려면 복합 객체 내에 있는 모든 객체들의 인터페이스가 똑같아야 합니다. 인터페이스를 통일시키다가 보면 객체에 따라 아무 의미가 없는 메소드도 생길 수 있습니다.
      의미없는 메소드의 처리 방법
      1. 아무일도 하지 않거나 널 또는 false를 상황에 맞게 리턴하는 방법
      2. 예외를 던지는 방법

    스테이트 패턴(State Pattern) : 객체의 내부 상태가 바뀜에 따라서 객체의 행동을 바꿀수 있습니다. 마치 객체의 클래스가 바뀌는 것과 같은 결과를 얻을 수 있습니다.

    • 객체에 수많은 조건문을 집어넣는 대신에 사용할 수 있는 패턴

    프록시 패턴(Proxy Pattern) : 어떤 객체에 접근을 제어하기 위한 용도로 대리인이나 대변인에 해당하는 객체를 제공하는 패턴

    의존성 뒤집기 원칙에 위배되는 객체지향 디자인을 피하는데 도움이 되는 가이드 라인

    • 어떤 변수에도 구상 클래스에 대한 레퍼런스를 저장하지 맙시다
    • 구상 클래스에서 유도된 클래스를 만들지 맙시다.
    • 베이스 클래스에 이미 구현되어 있던 메소드를 오버라이드하지 맙시다.

    감상문 : OOP의 가장 이상적인 모델
    인터페이스로 통신 및 접근을 하고, 구현체는 추상화되어 있어서 인터페이스 기반으로 설계를 한다. 객체를 생성하는 코드를 남발하지 않고, 한군데서 관리하도록 한다.
    강력한 추상화,캡술화만이 OOP를 잘하는 지름길이다.



    참고 서적

    Head First Design Pattern - 에릭프리먼

    Head First Design Patterns

    케이시 시에라 / 한빛미디어

    참고 article
    Open-Closed Principle
    http://www.zdnet.co.kr/builder/dev/modeling/0,39031637,39134727,00.htm
    인터페이스 분리의 원칙
    http://www.zdnet.co.kr/builder/dev/modeling/0,39031637,39139151-1,00.htm
    리스코프 치환 원칙
    http://www.zdnet.co.kr/builder/dev/modeling/0,39031637,39137043,00.htm
    단일 책임 원칙(Single Responsibility Principle)
    http://www.zdnet.co.kr/builder/dev/modeling/0,39031637,39135552-1,00.htm

  • 평소 관심이 많은 이슈중에 하나였는데, 나의 생각을 표현한 문구가 몇개 있어서 뽑아서 적어본다.

    JDBC의 일반적인 프로그램밍 같은 절차지향적인 개발방법을 사용하여도 Domain Model 근거로 설계할 수 있는 방법을 찾아야하지 않을까 생각됩니다. 

    즉, 제 의견은 꼭 Tool을 사용하지 않아도 가능하다!!는 의견입니다.

    - Earnest

    설계에 대한 부분에 대한 이야기를 하자면, 모든 것을 설계하는 것은 어려운 일이다. 추상적인 부분을 객체지향으로 설계를 하고, 데이터를 저장하는 퍼시스턴트 영역은 최소한의 function으로 구현을 한다면 현재 시점에서는 이상적이 아닐까?

    tool의 도움을 받으면 좀더 빠르고, 쉽게 패턴과 설계를 할수 있다는 강점은 있습니다.

    이상과 현실에 대한 이야기가 많다고 생각을 한다.
    이상에 가깝게 해결할 수 있는 사람이 능력이 있는 사람이지 않을까?

    Domain Model과 Data Model은 어떤 차이가 있나요?
    http://www.javaservice.net/~java/bbs/read.cgi?m=resource&b=discussion&c=r_p&n=1150848847&p=1&s=t#1150848847

    구현이 아닌 인터페이스를 바탕으로 프로그래밍을 하면, 유연성과 확장성이 뛰어난 코드를 만들 수 있습니다.



    interface

    http://www.martinfowler.com/bliki/ImplicitInterfaceImplementation.html

    http://homepage.mac.com/keithray/blog/2006/01/06/



    Minimal Interface : 사용자가 원하는 기능을 모두 제공하는 범주내에서 가장적은 수의 메소드만 갖도록 API를 설계하는 것이다.

    http://blog.empas.com/ahnyounghoe/read.html?a=11710135

    http://younghoe.info/33

    http://younghoe.info/35



    인터페이스를 익히는데는 시간이 필요하다. 많은 메소드를 인터페이스로 갖는 클래스를 잘 쓰이지 않을 뿐 아니라 외면 당하기 일쑤다. 적은 수의 집약적인 기능을 갖도록 메소드를 유지해야 사용자들이 클래스를 이해하고 사용하는데 수월하다.


    자바나 C# 의 interface 키워드를 사용하는 경우처럼 타입으로 정의한 순수 인터페이스를 사용하는 경우라면 메소드 숫자를 줄여야 할 이유가 또 있다. 인터페이스 구현자의 부담을 줄여야 한다는 점이다. 인터페이스의 메소드 숫자가 많으면 이를 모두 구현해야 하기 때문에 상당한 양의 작업이 요구된다. (추상 클래스를 mixin 으로 활용하면 부담을 줄일 수 있다.)


    Human Interface : Minimal Interface의 반대개념

    http://blog.empas.com/ahnyounghoe/read.html?a=11685433



    Fluent Interface

    http://martinfowler.com/bliki/FluentInterface.html

    http://blog.empas.com/ahnyounghoe/read.html?a=11849977&c=1139862



    Duck Interface

    http://martinfowler.com/bliki/DuckInterface.html

    http://blog.empas.com/ahnyounghoe/read.html?a=11888723&c=1139862



    나같은 경우는 경험상 Minimal Interface가 더 유용할거라고 생각을 한다.
    단일 책임 원칙(Single Responsibility Principle)
    http://www.zdnet.co.kr/builder/dev/modeling/0,39031637,39135552-1,00.htm

    하나의 클래스는 하나의 책임만을 가져야 한다. 하나의 클래그 안에 필요에 의해 두 가지 책임이 공존할 때 서로의 의존관계는 심각하게 강결합도기 때문에 변경에 대한 충격이 전달될 수밖에 없다.

    OCP는 확장이 설계의 포인트였다면, 단일 책임 원칙은 변경이 관전 포인트이다. 이 변경의 거북함을 조장하는 요소는 서로 다른 책임이 혼재해 있다는데 있다.

    잘못된 설계 - 액티브 오브젝트 패턴

    좋은 디자인 설계 - 데이터 맵퍼 패턴, 데이터 맵퍼를 사용하면 Person객체의 이용방식도 자연스럽게 DB관련 부분과 Person사용으로 분리된다.
    사용자의 Person객체에 대한 책임을 사용하는 목적과 방법이 명확해진다.(Person객체의 인터페이스인지, DB관련 작업인지)

    설계자는 분리의 크기(granularity)를 고민한다.
    • fine-grained : 미세단위로 구분
    • coarse-grained : 입도가 큰 단위로 구분
    • 선택의 기준은 복잡도,크기,용도가 된다. 복잡도가 높고 부피가 큰데 반해 그 용법이 단순하다면, coarse-grained가 적합하다. 역으로 복잡도가 낮고 부피가 작으며 용법이 다양하다면 fine-grained가 적합하다.
    일반적인 식별자 맵패턴이 사용

    높은 응집도(High Cohesion), 낮은 결합도(Loose Couplimng)
    : 이것은 현재 모든 소프트웨어 시스템 고유의 유지보수성과 적응성을 측정하는 가장 좋은 방법으로 사용되고 있다. 소프트웨어 디자인 뿐만 아니라 아케텍쳐 평가에도 이 원리가 기준이 되는데, 그 이유는 이 원리의 적용 효과가 아주 명백하기 때문이다. 이 원리의 예외는 거의 찾아보기 힘들만큼 보편성을 가지고 있어서 마치 물리학의 엔트로피 법칙처럼 절대적인 기반원리를 제시한다. 반대로 낮은 응집도, 높은 결합도를 가지는 디자인은 변경,확장 단계에서 많은 비용을 지불해야 한다.
    • 응집도 : 하나의 클래스가 하나의 기능(책임)을 순도 높게 담당
      * 기능적 응집 - 일관된 기능들이 집합된 경우
      * 순차적 응집 - 한 클래스 내에 등장하는 하나의 소작업(메소드)의 결과가 다음 소작업의 입력으로 사용되는 관계(파이프라인 방식의 처리 체인 관계)
      * 교환적 응집 - 동일한 입력과 출력 자료를 제공하는 메소드들의 집합을 말하며, 팩토리 클래스는 전형적인 교환적 응집도가 높은 인터페이스를 갖는다.
      * 절차적 응집 - 순서적으로 처리되어야 하는 메소드들이 그 순서에 의해 정렬되는 응집관계
      * 시간적 응집 - 시간에 흐름에 따라 작업 순서가 정렬되는 응집관계
      * 논리적 응집 - 유사한 성격의 개체들이 모여 있을 경우를 말하며 java.io클래스들의 경우가 대표적인 예이다.
    • 결합도 : 클래스간의 서로 다른 책임들이 얽혀 있어서 상호의존도가 높은 정도
      * 자료 결합 - 두 개 이상의 클래스가 매개변수에 의해서 결합 관계를 가지므로 낮은 수준의 결합도로 연관되는 경우
      * 스탬프 결합 - 자료 결합의 경우에서 매개변수 일부만을 사용하는 경우
      * 제어 결합 - 두 클래스간이 제어 이동이 매개변수를 이용하여 사용되는 경우
      ex) Command Pattern
    엔터프라이즈 애플리케이션 설계시 요소
    • -데이터 접근의 동기화
    • -동시성 처리
    • -풀링
    • -O/R 맵핑

    --> 각 책임들을 담당하는 클래스들을 분리시키고 이들 간의 관계를 잘 정의할수록 복잡도는 감소하고 아키텍쳐는 깨끗해진다.


    예를들면, 현재 제공되는 DB관련 프레임워크는 이 책임들을 맡는 기능을 구현한 녀석들이다. SRP를 적용하면 무엇보다도 책임 영역이 확실해지기 때문에 한 책임의 변경에서 다른 책임의 변경으로의 연쇄작용에서 자유로울 수 있다.

    동일한 책임을 갖는 여러 메소드들이 분리된다.
    ex) isnert, delete, update, load

    여러 원인에 의한 변경 : 하나의 클래스에 책임이 혼재하고 있엉서 하나의 책임의 변화가 다른 책임에 영향을 준다.
    • Extract Class는 혼재된 각 책임을 각각의 개별 클래스로 분할하여 클래스 당 하나의 책임만을 맡도록 하는 것이다. 여기서 관건은 책임만 분리하는 것이 아니라 분리된 두 클래스간의 관계의 복잡도를 줄이도록 설계하는 것이다.
    • 만약 Extract Class된 각각의 클래스들이 유사하고 비슷한 책임을 중복해서 갖고 있다면 Extract Superclass를 사용할 수 있따. Extract class된 각각의 클래스들의 공유되는 요소를 부모 클래스로 정의하여 부모 클래스에 위임하는 기법이다.. 따라서 각각의 Extract Class들의 유사한 책임들은 부모에게 명백히 위임하고 다른 책임들은 각자에게 정의할 수 있다

    산탄총 수술의 냄새는 하나의 책임이 여러 클래스에 분산되어 있기 때문에 발생한다.
    특히 설정 정보, 로깅, DB처리에서 발생하기 쉽다.

    '여러 원인에 의한 변경'과 '산탄성 수술'이란 악취를 SRP를 어긴 신호로 여기고 제거한다면 여러 곳으로 확산되지 않을 뿐 아니라 책임을 적절히 분배함으 인해 코드의 가독성 향상, 유지보수 용이라는 이점까지 누릴 수 있다. 적절한 책임 분배는 객체지향 원리들의 대전제 격인 OCP뿐 아니라 다른 원리들들 적용하는 기초가 되어준다.

    핵심 리팩토링 기법과 책임 분배
    : 할 수만 있다면, '사후 대처'보다는 '사전 예방'이 더 좋은 해결책이다.

    SRP를 적용하면 클래스들의 숫자가 늘 수는 있다. 하지만, 클래스 숫자의 증가가 프로그램 복잡도 증가와 비례하는 것은 아니다. 오히려 SRP를 잘 따르는 프로그램은 절절한 책임 분배로 인해 클래스 숫자와 프로그램의 복잡도가 반비례하는 경향이 있다고도 할 수 있게 된다.

    실제로 단순한 것이 위대한 것이다. 그리고 이 단순함의 중심에는 단일 책임의 원칙이 있다

    개방-패쇄 원칙( Open-Closed Principle)
    http://www.zdnet.co.kr/builder/dev/modeling/0,39031637,39134727,00.htm


    확장되는 것은 변하지 않은 것을 엄격히 구분해야 한다. 변하는 것은 가능한 변하기 쉽게, 변하지 않는 것은(패쇄돼야 하는 것은) 변하는 것에 영향을 받지 않게 설계를 한다. 다음으로 두 모듈이 만나는 지점에 인터페이스를 정의해야 한다. 변하는 것과 변하지 않는 모듈의 교차점으로 서로를 보호하는 방죽역할을 한다.

    서버에 있어서 인터페이스는 확장의 내용이 정의되고 이 규약에 따라 확장이 구체화하는 역할을 한다. 따라서 인터페이스는 서비스 내용을 추상화하는 형태로 제공되므로 인터페이스 설계에 주의가 필요하다. 또한 인터페이스는 클라이언트에 있어서 서버의 확장,변경에 따른 클라이언트의 변경을 무색하게 하는 방패가 된다. 서버에서는 인터페이스 규약에 의해서만 확장 변경되기 때문이다. 따라서 안정된 계약에 의한 설계를 보장한다.



    객체간의 관계를 단순화해 복잡도를 줄이고, 확장,변경에 따른 충격을 줄이는 데 있다.

    주의사항
    • 확장되는 것과 변경되지 않는 모듈을 분리하는 과정에서 크기 조절에 실패하면 오히려 관계가 더 복잡해져서 설계를 망치는 경우가 있다. 설계자의 좋은 자질 중 하나는 이런 크기 조절과 같은 갈등 상황을 잘 포착하여 비장한 결단을 내릴 줄 아는 능력에 있다.
    • 확장을 보장하는 open모듈 영역에서 예측하지 못한 타입을 만났을 때 인터페이스를 변경하려는 안과 어댑터를 사용하려는 안 사이에서 갈등하게 된다. 보통 후자를 선택한다. 한번 정해진 인터페이스는 시간이 갈수록 사용하는 모듈이 많아지기 때문에 바꾸는데 엄청난 출혈을 각오해야 한다. 즉, 인터페이스는 가능하면 변경해서는 안된다. 따라서 인터페이스를 정의할 때 여러 경우의 수에 대한 고려와 예측이 필요하다. 물론 과도한 작업은 불필요한 작업을 만든다. 설계자는 적절한 수준의 예측 능력이 필요한데, 설계자의 또 하나의 자질은 예지력이다
    • 인터페이스 설계에서 적당한 추상화 레벨을 선택하는 것이 중요하다. 추상화란 다른 모든 종류의 객체로부터 식별될 수 있는 객체의 본질적인 특징이다.

    객체지향원칙 - 이용현님 블로그
    http://blog.naver.com/tb/yohlee93/30005284579
    C언어를 하다가 C++과 자바를 한 것이 2000년도인가 봅니다. 객체지향을 억지로 머릿속에 넣고, 개념없이 사용을 했던거 같습니다. 10년에 절반정도 시간이 되니, 이제 조금씩 객체지향이 눈에 보이기 시작합니다. 그래서 저도 다시 객체지향과 패턴 등등을 다시 살펴보고 있죠. 어린 시절에 잘 안보이던 글귀들이 이제는 조금씩 보이기 시작하네요

    물론, 개념 자체가 시간이 흐르면서 더 완숙해지고, 많은 best practice들이 나와서 좀더 활용이 가능한 실질적인 패턴과 권장/추천하는 방식이 생겨나고, 많은 프레임워크들이 등장을 했습니다. Struts, webwork, Spring 등등도 중요하지만, 그것들이 만들어질 수 밖에 없었던 필연적인 이유는 좀더 객체지향을 잘 하기 위함이 아닐까 생각해 봅니다. 단순하게 프레이워크를 사용하는데 그치지 않고, 좀더 객체지향적으로 디자인이 잘된 어플리케이션을 설계할 수 있으면 좋겠습니다...^^

    BLOG main image
    OOP and Java by ologist

    공지사항

    카테고리

    All (649)
    private!! (106)
    WEB & IT (140)
    Developer (400)