프로그램, 제품, 시스템, 시스템 제품
코드의 줄 수와 팀 크기만이 프로젝트의 크기에 영향을 미치는 것은 아니다. 최종적인 소프트웨어의 품질과 복잡성이 보다 미묘한 영향을 미친다. 원래의 기가트론은 작성하고 디버깅하는 데 한 달이 걸렸을 뿐이었다. 그 프로그램은 한 사람에 의해서 작성되고 테스트되고 문서화된 단일 프로그램이었다. 만약 2,500줄짜리 기가트론이 한 달 걸렸다면, 왜 25,000줄로 확장된 기가트론은 스무 달이 걸렸을까?
가장 간단한 소프트웨어의 종류는 그 프로그램을 작성한 한 사람 또는 몇 사람에 의해서 사용되는 단일 "프로그램"이다.
보다 정교한 프로그램의 종류는 원래의 개발자가 아닌 다른 사람들에게 의해서 사용될 목적으로 만들어진 프로그램, 즉 소프트웨어 "제품"이다. 소프트웨어 제품은 제품이 작성된 것과는 다른 환경에서 사용된다. 따라서 제품이 릴리즈되기 전에 광범위하게 테스트되고 문서화되며, 다른 사람에 의해서 유지 보수될 수 있다. 소프트웨어 제품은 소프트웨어 프로그램보다 개발하는데 약 3배의 비용이 든다.
함께 작동하는 프로그램 그룹을 개발할 때에는 또 다른 정교함이 요구된다. 그런 그룹을 소프트웨어 "시스템"이라고 부른다. 시스템 개발은 통합되는 부분들 사이의 인터페이스를 개발하는데에 따른 복잡성과 주의가 요구되기 때문에 간단한 프로그램을 개발하는 것보다 좀 더 복잡하다. 전체적으로, 시스템도 간단한 프로그램을 개발하는 것보다 3배 정도의 비용이 든다.
"시스템 제품"이 개발될 때에는, 제품과 시스템의 여러 부분들을 다듬어야 한다. 따라서 시스템 제품은 간단한 프로그램보다 9배 정도의 비용이 든다.(Brooks 1995, Shull 외. 2002)프로그램과 제품, 시스템, 시스템 제품 간의 매끄러움과 복잡성 간의 차이를 제대로 평가하지 못하는 것이 견적 오류의 일반적인 원인이다. 예를 들어, 프로그램을 작성해 본 경험이 있는 프로그래머가 자신의 경험을 토대로 시스템 제품을 작성하기 위한 일정을 추정하게 되면 거의 10배 정도 낮게 추정할 수 있다. 만약 2K 프로그램을 개발하기 위해서 걸리는 시간을 추정하기 위하여 2K줄짜리 코드를 작성했던 경험을 사용한다면, 여러분이 예상한 시간은 실제로 프로그램을 개발하면서 들어가는 모든 활동들을 수행하기 위해서 필요한 전체 시간의 65%일 뿐이다.
2K줄짜리 코드를 작성하는 것은 2K줄을 포함하고 있는 전체적인 프로그램을 작성하는 것 만큼 오랜 시간이 걸리지 않는다. 만약 구현이 아닌 활동 등에 걸리는 시간을 고려하지 않는다면, 구현은 여러분이 예측한 것보다 50% 정도의 시간이 더 걸릴 것이다.
크기가 커질수록, 구현은 프로젝트에 들어가는 전체적인 노력에서 보다 작은 부분이 된다. 만약 여러분의 견적을 구현에서의 경험에만 기초한다면, 견적 오류는 증가할 것이다. 만약 32K 프로그램을 개발하는 데 걸리는 시간을 추정하기 위해서 2K 구현 경험을 사용했다면, 여러분의 견적은 단지 필요한 전체 시간의 50%가 되고, 개발은 추정한 것보다 100%의 시간이 더 걸릴 것이다.
여기서의 견적 오류는 전적으로 더 큰 프로그램을 개발하는 데 있어서 크기가 미치는 영향을 이해하지 못했기 때문일 것이다. 또한, 만약 단일 프로그램이 아닌 제품에 요구되는 추가적인 섬세함 정도를 고려하지 못한다면, 오류는 3배 이상으로 증가할 수 있다.
아무래도 가장 중요한 듯 싶다.
나는 항상 일정에 쫓기 업무는 싫어서
항상 내 일정을 내 스스로 잘 조정할려고 노력하는 타입이다.
항상 퇴근 시간이 되면 그 전에 했던 일들을 정리하고
내일 그리고 이번주에 해야할 일 전체적인 진행상황들을
달력을 보면서 머릿속으로 정리한다.
파일 업로드 서블릿.
파일 업로드가 안되네 -_-;;
=_=..
일단 소스라도.
서블릿 맵핑 설정
일반적으로 쓰이는 버전 번호 규칙에 대해서 알아보자.(자바쪽)
보통 버전은 다음과 같은 네 가지 부분으로 구성된다.
major.minor.service.qualifier
각각의 의미에 대해서 알아보자
- major(주버전) : 주 버전의 변경은 하위 호환이 보장되지 않는 등의 매우 큰 변화를 의미한다.
- minor(부버전) : 부 버전의 견경은 플러그인의 새 버전이 기존 버전과 하위 호환은 되지만 기능과 API가 추가 되었다는 의미이다.
- service(서비스버전) : 서비스 버전은 기존 버전에 대해 버그 수정 또는 사소한 구현(숨겨진)이 추가 되었다는 의미이다.
- qualifier(수식자) : 수식자는 런타임에서는 인식하지 않는다. 수식자는 표준 문자열을 통해서 비교된다.
이클립스 및 거의 모든 jar 파일들의 위의 버전 번호 규칙을 사용한다.
이 버전 번호 규칙을 알고 있으면 이전 버전에 바뀐것이 무었인지 명세를 살펴보지 않아도
어느정도 감을 잡을 수 있기 때문에 도움이 된다.
출처 : 이클립스 RCP
의사코드 프로그래밍 프로세스.
CODE COMPLETE 9장.
의사코드 프로그래밍에 대해 이야기 하고 있다.
뭐.. 간단히 슈도 코드를 사용해서 작성하고 이를 코드로 바꾼다는 이야기.
나도 아직 경험이 적기 때문에 완벽히 적용하고 있지는 않지만 적용하기 위해 노력해야 겠다.
요즘에야 TTD 나 리팩토링 기법도 자주 사용되고 있지만,
그전에 슈도 코드로 미리 작성을 해보고 이를 가지고 TTD를 적용하여 개발 하는게 좋은 것 같다는 생각이 든다.
가장 중요한 건 "컴파일 한 번만 더" 증후군에 걸리지 않는다.
공감하는 내용.
이는 조급하게 오류를 유발할 수 있는 변경을 하게 만들고,
길게 봤을 때 더 많은 시간이 걸리게 한다.
루틴이 맞다는 확신이 들 때까지 컴파일 하지 않도록 하자.
웹 브라우저 테스트 해보기 전에 지금 무엇을 테스트하려는지 명확히 하고 지금 테스트 하려는 코드가 올바르게 동작 하는지 충분한 생각을 한 후 테스트 해보도록 하자.
뒷 부분 요점 정리를 옴겨 보면.
- 클래스와 루틴의 구현은 반복적인 경향이 있다. 특정한 루틴을 구현하는 도중에 얻게 되는 내용들이 클래스의 설계에 영향을 미치는 경향이 있다.
- 훌륭한 의사코드를 작성하기 위해서는 이해 가능한 영어를 사용하고, 단일 프로그래밍 언어에 특화된 기능들을 피하고, 의도 수준에서 작성해야 한다.( 어떻게 처리할 것인지 보단느 설계가 무엇을 하는지 기술한다.)
- 의사코드 프로그래밍 프로세스는 상세 설게에 유용한 도구이며 코드 작성을 쉽게 만든다. 의사코드는 곧바로 주석으로 변환되며, 변환된 주석은 정확하고 유용하다.
- 여러분이 생각한 첫 번째 설계로 결정하지 않는다. 의사코드에서 여러 가지 접근 방법을 이용하여 반복하고 코드를 작성하기 전에 가장 좋은 접근 방법을 선택한다.
- 각 단계에서 자신의 작업을 검사하고 다른 사람들도 여러분의 작업을 검사하도록 한다. 그렇게 하면, 가장 적은 노력을 들였을 때 가장 적은 비용 수준에서 실수를 잡을 수 있을 것이다.
클래스를 작성 하는 이유
클래스를 작성 하는 이유
실세계의 객체를 모델링하라
- 실세계의 객체를 모델링하는 것이 클래스를 생성하는 유일한 이유는 아니겠지만, 그래도 여전히 정당한 이유이다! 여러분의 프로그램이 모델링하는 실세계의 모든 객체 형에 대한 클래스를 생성하라. 객체에 필요한 데이터를 클래스에 입력하고, 객체의 행위를 모델링하는 서비스 루틴들을 구축한다.
추상 객체들을 모델링하라
- 클래스를 생성하기 위한 또 다른 정당한 이유는 추상 객체, 즉 실체가 없는 실세계의 객체지만 다른 실질적인 객체의 추상화를 제공하는 객체를 모델링하기 위한 것이다. Shape 객체가 좋은 예이다. Circle과 Square는 실제로 존재하지만, Shape는 다른 구체적인 도형들에 대한 추상화이다.
프로그래밍 프로젝트를 진행할 때, 추상화는 Shape에서처럼 미리 만들어져 있지 않기 때문에 분명한 추상화를 이끌어내기 위해서 더욱 열심히 일해야 한다. 실세계의 엔티티로부터 추상적인 개념을 만들어내는 과정은 결정저이지 않으며, 서로 다른 설계자들이 서로 다른 일반 법칙들을 추상화할 것이다. 예를 들어, 여러분이 원이나 정사각형, 삼각형과 같은 기하학적인 모양을 모른다면, 찌그러진 모양, 줄기 모양, 폰티악 아즈텍 모양과 같이 특이한 모양을 생각해낼 것이다. 적절한 추상화 객체를 생각해내는 것은 객체 지향 설계에서 가장 어려운 난제 중 하나이다.
복잡성을 줄여라
- 정보를 감추기 위해서 클래스를 생성하면 그러한 정보에 대해 생각할 필요가 없을 것이다. 물론, 클래스를 작성할 때에는 정보에 대해서 생각해야 할 것이다. 하지만 클래스를 작성하고 난 후에는, 세부사항들을 잊고 내부 작동 방식에 대해서 몰라도 클래스를 사용할 수 있어야 한다. 클래스를 생성하는 또 다른 이유들에는 코드의 크기를 최소화하거나, 유지 보수성을 향상시키거나, 정확성을 향상시키기 위한 것들이 있다. 하지만 클래스의 추상적인 능력이 없다면, 복잡한 프로그램을 지적으로 관리하는 것이 불가능할 것이다.
복잡성을 고립시켜라
- 복잡한 알고리즘이나 큰 데이터 집합, 뒤얽힌 통신 프로토콜 등 어떤 형태든지 간에 복잡성은 오류를 유발할 가능성이 있다. 오류가 발생했을 때, 오류가 코드 전체에 퍼져 있지 않고 클래스 내에 지역화되어 있다면 훨씬 찾기 쉬울 것이다. 오류를 수정하기위한 변경 사항들은 다른 코드에 영향을 미치지 않을 것이다. 왜냐하면 한 클래스만 변경되고 다른 코드는 건드리지 않을 것이기 때문이다. 만약 더 좋고, 간단하며, 신뢰할 수 있는 알고리즘을 발견했을 때, 해당 알고리즘이 클래스에 고립되어 있다면 오래된 알고리즘을 보다 쉽게 대체할 수 있을 것이다. 개발을 하는 도중에도 다양한 설계를 쉽게 시도해 볼 수 있고 가장 잘 작동하는 설계를 유지하기가 쉬울 것이다.
세부적인 정보를 숨겨라
- 세부적인 정보를 감추고자 하는 바람은, 세부 사항이 복잡한 데이터베이스에 대한 접근처럼 복잡하거나 특정한 데이터 멤버에 숫자나 문자가 저장되는 것처럼 평범한지에 상관없이 클래스를 생성하기 위한 훌륭한 이유이다.
변경의 영향을 제한하라
- 변경할 가능성이 있는 부분을 고립시켜서 변경의 영향을 단일 클래스나 적은 수의 클래스로 제한한다. 변경될 가능성이 제일 높은 부분을 가장 쉽게 변경할 수 있도록 설계하라. 변경할 가능성이 있는 부분에는 하드웨어에 의존적인 부분, 입력/출력, 복잡한 데이터 형, 비즈니스 규칙들이 있다.
전역 데이터를 숨겨라
- 만약 전역 데이터를 사용할 필요가 잇다면, 세부적인 구현 사항을 클래스 인터페이스 뒤에 숨길 수 있다. 접근 루틴들을 통해서 전역 데이터를 다루면, 적연 데이터를 직접적으로 다루는 것에 비해서 여러 가지 이점을 제공한다. 여러분은 프로그램을 변경하지 않고 데이터의 구조를 변경할 수 있다. 여러분은 데이터에 대한 접근을 감시할 수 있다. 또한, 접근 루틴을 사용하는 원칙을 지키면 그 데이터가 정말로 전역인지에 대해서 생각하게 된다. 실제로 "전역 데이터"가 단순한 객체 데이터일 뿐이라는 점이 명백해지는 경우가 종종 있다.
매개변수의 전달을 간소화하라
- 만약 어떤 매개변수를 여러 루틴들 사이에서 전달하고 있다면, 매개변수를 객체 데이터로 공유하는 클래스에 이 루틴을 포함시켜야 할 필요성이 있다는 것을 암시한다. 매개변수 전달을 간소화하는 것 자체가 목표가 아니지만, 수많은 데이터를 전달한다는 것은 다른 클래스 구성이 더 잘 작동할 것임을 말해준다.
중앙 집중 관리하라
- 한 곳에서 작업을 처리하는 것은 좋은 아이디어이다. 제어에는 많은 형식이 있다. 테이블에 있는 엔트리들의 수에 대한 정보도 한 형식이고, 디바이스들(파일, 데이터베이스 연결, 프린터 등)의 관리도 또 다른 형식이다. 그리고 데이터베이스로부터 읽고 쓰는 클래스를 작성하는 것도 집중화된 관리의 또 다른 형식이다. 만약 데이터베이스가 파일이나 메모리 내의 데이터로 변환되어야 한다면, 그러한 변경 사항이 한 클래스에만 영향을 미칠 것이다.
집중화된 관리의 기본 개념은 정보 은닉과 유사하지만, 여러분의 프로그래밍 도구 상자에 추가할 가치가 있는 유일한 경험적인 힘을 갖고 있다.
코드의 재사용을 도와라
- 코드를 잘 분리된 클래스에 입력하면 하나의 큰 클래스에 포함되어 있는 것보다 다른 프로그램에서 쉽게 재사용될 수 있다. 비록 어떤 코드 섹션이 프로그램내의 한 곳에서만 호출되고 큰 클래스의 일부로써 이해하ㅣㄱ 쉽다고 하더라도, 해당 코드 섹션이 다른 프로그램에서 사용될 것 같다면 별도의 클래스에 입력 하는 것이 좋다.
프로그램군(family)을 위한 계획을 작성하라
- 만약 프로그램이 변경될 것으로 예상하고 있다면, 그러한 부분들을 별도의 클래스로 입력하여 고립시키근 것이 좋다. 그러면 프로그램의 나머지 부분에 영향을 미치지 않고 클래스를 변경할 수 있거나, 대신 완전히 새로운 클래스를 입력할 수 있다. 단순히 한 프로그램의 모습만이 아니라 전체 프로그램군의 모습을 생각하는 것이 전체적인 변경 내용을 예상하는 데 크게 도움이 된다.
연관된 기능을 패키지화하라
- 만약 여러분이 정보를 숨기거나, 데이터를 공유하거나, 유연한 계획을 세울 수 없는 경우에는, 관련된 기능들을 삼각법 함수들, 통계 함수들, 문자열 처리 루틴들, 비트 처리 루틴들, 그래픽 루틴들과 같이 적당한 그룹으로 패키지화할 수 있다. 클래스는 연관된 기능들을 결합하는 한 가지 수단이다. 여러분은 언어에 따라서 패키지나 네임 스페이스, 또는 헤더 파일을 사용할 수 있다.
특정한 리팩토링을 수행하라
- 특정한 리팩토링을 수행하면 하나의 클래스를 두 개의 클래스로 변환하고, 델리게이트를 감추고, 미들 맨을 제거 하고, 확장 클래스를 만다는 방법으로 ㅅ로운 클래스들이 만등러진다. 이 섹션을 통해서 소개된 임무를 더 잘 달성하고자 한다면 이러한 새로운 클래스를 만들어 볼 수 있다.
피해야 할 클래스
만능(GOD) 클래스를 생성하지 말라
- 모든 것을 알고 있고 모든 것을 할 수 있는 전지전능한 클래스를 생성하지 말라. 만약 어떤 클래스가 Get()과 Set() 루틴을 사용하여 다른 클래스로 부터 데이터를 얻는 데 시간을 보내고 있다면(즉, 다른 사람의 일에 끼어들어서, 무엇을 해야 하는지 말하고 있다면), 그 기능은 만능(god) 클래스보다 다른 클래스로 구성하는 것이 더 좋지 않은지 물어 보라
관련이 없는 클새스들을 제거하라
- 만약 클래스가 행위는 없이 데이터로만 구성된다면, 그 클래스가 정말로 클래스인지 확인해 보고, 그 클래스를 강등시켜 클래스의 멤버 데이터가 하나 이상의 다른 클래스들의 특성이 될 수 있는지 골해 본다.
동사가 따라오는 클래스를 피하라
- 데이터는 없이 행위로만 구성된 클래스는 일반적으로 클래스가 아니다. DatabaseInitialization()이나 StringBuilder()와 같은 클래스를 다른 클래스의 루틴으로 변환할 것을 고려해 본다.
체크 리스트 : 클래스의 품질
추상 데이터 형
- 프로그램에 있는 클래스들을 추상 데이터 형으로 생각하고, 그러한 관점에서 클래스의 인터페이스들을 평가해 보앗는가?
추상화
- 클래스가 핵심적인 목적을 갖고 있는가?
- 클래스의 이름이 잘 지어졌고, 클래스의 이름이 핵심적인 목적을 설명하고 있는가?
- 클래스의 인터페이스가 일관성 있는 추상화를 제공하는가?
- 클래스의 인터페이스가 클래스의 사용 방법을 분명히 하고 있는가?
- 여러분이 클래스의 서비스가 어떻게 구현되었는지에 대해서 생각할 필요가 없을 정도로 클래스의 인터페이스가 추상적인가? 클래스를 블랙박스로 취급할 수 있는가?
- 다른 클래스들이 클래스의 내부 데이터를 쓸데없이 참견할 필요가 없을 만큼 클래스 서비스가 완벽한가?
- 관련 없는 정보를 클래스에서 제거 하였는가?
- 클래스를 컴포넌트 클래스로 분할하는 것에 대해서 생각해 보았는가? 그리고 최대한 분할하였는가?
- 클래스를 수정할 때, 클래스 인터페이스의 무결성을 유지하고 있는가?
캡슐화
- 클래스가 멤버에 대한 접근성을 최소화하고 있는가?
- 클래스가 멤버 데이터의 노출을 피하고 있는가?
- 클래스가 프로그래밍 언어가 허용하는 한 다른 클래스들로부터 세부적인 구현 사항들을 감추고 있는가?
- 클래스가 파생 클래스와 사용자들에 대한 가정을 피하고 있는가?
- 클래스가 다른 클래스에 독립적인가? 느슨하게 결합되어 있는가?
상속
- 상속이 "is a"관계를 모델링 하기 위해서만 사용되었는가?
- 클래스의 설명 문서가 상속 전략을 기술하고 있는가?
- 파생 클래스가 오버라이드 불가능한 루틴에 대해서 "오버라이딩"을 피하고 있는가?
- 공통적인 인터페이스, 데이터, 행위가 상속 트리에서 최대한 높은 곳에 있는가?
- 상속 트리가 적절하게 얕은가?
- 기본 클래스에 잇는 모든 데이터 멤버들이 protexted 대신 private 인가?
구현에 대한 다른 문제들
- 클래스가 7개 이하의 데이터 멤버들을 포함하고 있는가?
- 클래스가 다른 클래스에 대한 직접적이고 간접적인 루틴 호출을 줄였는가?
- 클래스가 반드시 필요한 경우에만 다른 클래스와 협력하는가?
- 모든 멤버 데이터가 생성자에서 초기화 되었는가?
- 만약 얕은 복사를 생성해야 하는 합당한 이유가 없다면, 클래스가 얕은 복사 대신 깊은 복사로 사용되도록 설계되었는가?
언어에 따른 문제
- 여러분이 사용하고 있는 프로그래밍 언어에서 클래스에 대한 이슈들을 조사하였는가?
apache commons Configuration
환경 설정 파일을 불러 들일때 사용하는 파일.
다양한 파일 포맷을 지원한다.
- Properties files
- XML documents
- Windows INI files
- Property list files (plist)
- JNDI
- JDBC Datasource
- System properties
- Applet parameters
- Servlet parameters
http://commons.apache.org/configuration/
저기 가면 다운 로드 받을 수 있다.
간단한 사용 설명은
http://moai.tistory.com/789
요기 블로그에 가서 확인
struts2 EL disabled.
If you have been developing Struts2 applications in version <= 2.0.9, there are two important compatibility issues that you must address before you can upgrade to 2.0.11 or 2.1. These are the portlet compatibility issues and EL expression issue in Struts2 tags.
1. Struts 2.0.9 contained a major security issue as detailed here. The problem was that using EL expressions and OGNL tags at the same time in Struts2 tags, malicious code could be executed. The fix in 2.0.11 was to disable EL expressions completely(!). This means that code written in 2.0.9 will break in 2.0.11 if you have used EL expressions in JSP. If you have a well tested production system, this means total nightmare. Well, now you are between devil and the sea!
스트럿츠 버전이 2.0.11로 올라가면서 EL 표현식이 사라졌다.
그래서 이전에 EL로 구현에 놓은 페이징 처리 페이지를 보면 TLD에러를 뿜어 냈나 보다.
=ㅅ=..
죈장.
햇갈려서 ... 검색하고 다니다가 찾았다...
http://www.struts2.org/struts2-compatibility-issues-el-expressions-disabled-in-2011/
여기가 발견한 페이지.
이제 EL은 버리고 OGNL로만 고고싱 하는거다.
일반적인 MIME 타입
application/pdf
video/quicktime
applicaton/java
image/jpeg
application/jar
application/octet-stream
application/x-zip
등등..
한달간 계획 이랄까..
회사에서 서블릿 + EJB를 써서 개발을 했기때문에..
서블릿과 EJB 를 한번 봐야겠다..
서블릿은 책으로 한번 공부했는데.. 기억이 ㄱ-..
EJB는 책만 =ㅁ=..
일단 서블릿 + JSP 로 공부좀 하고..
EJB도 병행해서 시작.!!!!
화이팅!
언젠가는 아키텍쳐가 될까?
생각을 해보지는 않았지만 나중에는 아마 해보고 싶을꺼 같다.
책 읽으면서 느끼는게 우왕.. 역시 아키텍쳐는 어렵군화.. -ㅂ-..
대규모 프로젝트를 진행해야 할때는 챙겨야 하는 선행 조건이 장난 아니게 많다 -ㅂ-...
code2 complete
chaptor 3 준비는 철저하게 : 선행조건 에 나온 요점 정리를 보면
- 구현을 준비함에 있어서 가장 중요한 목표는 위험 감소이다. 준비 작업이 위험을 증가시키지 않고 감소시킬 수 있도록 한다.
- 만약 품질이 뛰어난 소프트웨어를 개발하고 싶다면, 처음부터 끝까지 소프트웨어 개발 ㅗ가정 내내 품질에 대한 관심을 유지해야 한다. 초기의 품질에 대한 관심은 나중에 관심을 갖는 것보다 제품의 품질에 훨씬 큰 영향을 미친다.
- 프로그래밍을 시작하기 전에, 적절한 준비의 중요성과 함께 소프트웨어 개발 과정에 대해서 상사와 동료를 교육하는 일도 프로그래머의 몫이다.
- 프로젝트의 종류가 구현의 선생 조건에 중대한 영향을 미친다. 반복적으로 진행해야 하는 프로젝트가 있는 반면, 순차적으로 진행해야 하는 프로젝트도 있다.
- 만약 요구 사항 개발이 제대로 이루어지지 않았다면, 문제의 중요한 사항들을 놓칠 수 있다. 요구 사항 변경은 구현 다음 단계부터는 처음보다 20~100배 정도로 비용이 들기 때문에, 프로그래밍을 시작하기 전에 요구 사항이 맞는지 확인 해야 한다.
- 만약 구조적인 설계가 제대로 이루어지지 않았다면, 구현 시에 올바른 문제를 잘못된 방법으로 해결할 수 잇다. 잘못된 구조로 작성된 코드가 증가할수록 구조적인 변경 비용이 증가하므로, 아키텍처가 맞는지 확인해야 한다.
- 구현 선행 조건에 어떤 접근 방법을 적용햇는지 이해해야 하며, 그에 따라서 적절한 구현 방법을 선택한다.
프로젝트를 진행하면서 구현시에 항상 구현에만 급급하지 않고 프로젝트의 전체적인 모습을 볼 수 있도록 항상 생각하는 프로그래머가 되자. !!