완벽한 설계란 있을수 없겠지만, 완벽에 가까운 설계일수록 군더더기가 없고 단순한다.
설계에 있어 완벽함이란 더 이상 추가할 것이 없을 때 이루어지는 것이 아니라 더 이상 버릴 것이 없을 때 이루어진다.
- Eric S. Raymond
설계에 있어 완벽함이란 더 이상 추가할 것이 없을 때 이루어지는 것이 아니라 더 이상 버릴 것이 없을 때 이루어진다.
- Eric S. Raymond
어쩌어쩌하다가 우연히 블로그에서 아이디/별명 검색UI를 보았다.
아이디와 별명이 다른 필드임에도 불구하고, 아이디 or 별명이라는 인터페이스가 존재를 했다. 그것도 서버쪽 인터페이스가 아니라 일반적으로 많이 사용할 만한 클라이언트쪽 인터페이스였다.
처음에 기획의도는 한방에 편하게 검색하는 것이라고 생각은 들지만, 개발을 할때 개발자는 한번도 생각을 해서 기획자와 협의를 통해서 인터페이스를 바꾸어야 했지 않나 싶다. or관련된 쿼리의 퍼포먼스저하 문제는 공인된(?) 사실중의 하나이다. 실질적으로 이런 조금만 것들이 모여서 어플리케이션의 성능을 저하시킨다.
기획적으로 조금만 UI를 다르게 생각해서 비슷한 효과를 볼수 있는 방법이 있을듯한데, 굳이 or로만 해결할수 있게 화면을 구성한 것은 아쉬운 일이다.
웹에서의 화면 구성은 중요한 이슈중의 하나이다. 기획자가 미쳐 놓치고 간 부분이 있다면, 개발자가 advice를 통해서 불필요한 부하를 일으킬 필요는 없지 않을까?
개발을 할때도 고민하면서 창의적으로 업무를 수행할 필요가 있겠지만, 기획서, 스토리 보드를 확인할때도 좀더 고민하자.
객체지향의 기초
추상화 , 캡슐화 , 다형성 , 상속
객체지향의 원칙
디자인 원칙
전문용어의 위력
객체지향 패턴
스트래티지 패턴(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)를 똑같은 방법으로 다룰수 있습니다.
스테이트 패턴(State Pattern) : 객체의 내부 상태가 바뀜에 따라서 객체의 행동을 바꿀수 있습니다. 마치 객체의 클래스가 바뀌는 것과 같은 결과를 얻을 수 있습니다.
프록시 패턴(Proxy Pattern) : 어떤 객체에 접근을 제어하기 위한 용도로 대리인이나 대변인에 해당하는 객체를 제공하는 패턴
의존성 뒤집기 원칙에 위배되는 객체지향 디자인을 피하는데 도움이 되는 가이드 라인
감상문 : OOP의 가장 이상적인 모델
인터페이스로 통신 및 접근을 하고, 구현체는 추상화되어 있어서 인터페이스 기반으로 설계를 한다. 객체를 생성하는 코드를 남발하지 않고, 한군데서 관리하도록 한다.
강력한 추상화,캡술화만이 OOP를 잘하는 지름길이다.
참고 서적
Head First Design Pattern - 에릭프리먼
참고 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



--> 각 책임들을 담당하는 클래스들을 분리시키고 이들 간의 관계를 잘 정의할수록 복잡도는 감소하고 아키텍쳐는 깨끗해진다.
산탄총 수술의 냄새는 하나의 책임이 여러 클래스에 분산되어 있기 때문에 발생한다.
특히 설정 정보, 로깅, DB처리에서 발생하기 쉽다.
핵심 리팩토링 기법과 책임 분배
: 할 수만 있다면, '사후 대처'보다는 '사전 예방'이 더 좋은 해결책이다.
SRP를 적용하면 클래스들의 숫자가 늘 수는 있다. 하지만, 클래스 숫자의 증가가 프로그램 복잡도 증가와 비례하는 것은 아니다. 오히려 SRP를 잘 따르는 프로그램은 절절한 책임 분배로 인해 클래스 숫자와 프로그램의 복잡도가 반비례하는 경향이 있다고도 할 수 있게 된다.
실제로 단순한 것이 위대한 것이다. 그리고 이 단순함의 중심에는 단일 책임의 원칙이 있다

