1 / 37

Refactoring To Patterns 이동현

아 . 꿈 . 사 Annual Summary 2008. Refactoring To Patterns 이동현. Refactoring. Patterns. XP. 이 책은 . XP 에서 왜 패턴을 언급 하지 않는가 ? 마틴 파울러는 그의 저서에서 패턴을 고려한 리팩토링은 몇 가지 안 되었고 , 누군가 더 많은 패턴을 고려한 리팩토링을 써 주길 바랬다 . 좀 더 실용적인 예제가 필요했다 . Standing on the Shoulders of Giants. 일반적으로 . 패턴을 공부했다 .

kaoru
Télécharger la présentation

Refactoring To Patterns 이동현

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 아.꿈.사 Annual Summary 2008 Refactoring To Patterns이동현

  2. Refactoring Patterns XP

  3. 이 책은.. • XP에서 왜 패턴을 언급 하지 않는가? • 마틴 파울러는 그의 저서에서 패턴을 고려한 리팩토링은 몇 가지 안 되었고, 누군가 더 많은 패턴을 고려한 리팩토링을 써 주길 바랬다. • 좀 더 실용적인 예제가 필요했다.

  4. Standing on the Shoulders of Giants

  5. 일반적으로.. • 패턴을 공부했다. • 패턴은 많은 유용한 디자인 아이디어 전달. • 몇 가지 패턴 습득 후. • 스스로 좋은 소프트웨어 디자이너로 생각되어 흡족하다. • 그러나.. 가끔 over-engineering 에 .. • 경험이 쌓여 스킬이 늘어 나의 스타일에 변화가 생겼다. • XP의 수용으로 과도한 up-front 디자인의 자제.

  6. 이 책을 쓴 이유 • Over-Engineering • Under-Engineering • The Pattern Panacea • Test Driven Development and Continuous Refactoring • Refactoring and Patterns • Evolutionary Design

  7. Over-Engineering • 시스템의 미래의 요구사항을 알고 있다는 착각의 발현. • 예측이 틀리면? -> 모든 게 낭비. • 결과로 불필요한 복잡성의 증가와 부정적 side-effect. • 아주 조용하게 일어난다.

  8. Under-Engineering • Poor Design • 시간이 없다.. 빨리 빨리.. 그래서.. • 좋은 디자인이 뭐야? 부족한 실력.. • 새로운 기능을 빨리 보고싶다. • 한번에 여러 프로젝트 참여. • 결국.. • Fast, slow, slower 리듬으로 귀결.

  9. The Pattern Panacea • 닭 잡는데 소 잡는 칼 쓰기.. • 패턴 중독.. • 디자인 패턴은 만병통치약이 아니다. • 진정으로 더 나아가기 위해서는 패턴에 대한 맹신을 접어라.

  10. TDD & Continuous Refactoring • Ask • Respond • Refind • Repeat

  11. Refactoring and Patterns • 마틴의리팩토링을 적용하면서 디자인 개선에 패턴이 도움이 되는걸 발견했다. • 디자인 패턴만 공부하면 원래의 핵심인 동기에 대한 부분을 놓치기 쉽다. - Intent 에 집중하게 된다. • Applicability section 이라도 자세히 봤다면 .. Our design patterns capture many of the structures that result from refactoring... Design patterns thus provide targets for your refactoring. [DP, 354] There is a natural relation between patterns and refactorings. Patterns are where you want to be; refactorings are ways to get there from somewhere else. [F,107]

  12. Evolutionary Design 조상으로부터 물려받은 것이 있거든 그것을 얻되 네 것이 되게 하라. - Goethe 결과 보다는 과정을 공부하는 것이 중요하다. 진짜 지혜는 그 과정 속에 숨어 있다. 패턴을 리팩터링과 별개로 생각 하지 말고, 리팩터링의 문맥에서 바라보라.

  13. Refactoring • 새로운 코드를 더 쉽게 추가할 수 있도록 하기 위해. • 기존 코드의 설계를 개선하기 위해. • 기존 코드를 더 잘 이해하기 위해. • 덜 짜증나는 코드로 만들기 위해. • 많은 눈. • John Thompson 씨의 모자가게 • 깨진 창문. • 작은 단계. • 점심도 못 먹고 한 리팩터링. • 설계 부채. • 이걸로 관리자를 설득 하라.

  14. Patterns • 패턴 목표 • 패턴 지향 • 패턴 제거

  15. Code Smells • 설계 문제 • 중복된 코드 • 코드의 의미가 불명확 함 • 코드가 복잡하다. • 이런 것들은 구체적인 가이드 라인이 되기엔 너무 추상적이다. • 구체적인 기준 제시.

  16. Catalog of Code Smells • Duplicated Code • Long Method • Conditional Complexity • Primitive Obsession • Indecent Exposure • Solution Sprawl • Alternative Classes with Different Interfaces • Lazy Class • Large Class • Switch Statements • Combinational Explosion • Oddball Solution

  17. Alternative Classes with Different Interfaces • Unify Interfaces with Adapter( 247 ). • Combinatorial Explosion • Replace Implicit Language with Interpreter(269) • Conditional Complexity • Replace Conditional Logic with Strategy(129) • Move Embellishment to Decorator(144) • Replace State-Altering Conditionals with State(166) • Introduce Null Object(301) • Duplicated Code • Form Template Method(205) • Introduce Polymorphic Creation with Factory Method(88) • Chain Constructors(340) • Replace One/Many Distinctions with Composite(224) • Extract Composite(214) • Unify Interface with Adapter(247) • Introduce Null Object(301) • Indecent Exposure • Encapsulate Classes with Factory(80) • Large Class • Replace Conditional Dispatcher with Command(191) • Replace State-Altering Conditionals with State(166) • Replace Implicit Language with Interpreter(269) • Lazy Class • Inline Singleton(114) • Long Method • Compose Method(123) • Move Accumulation to Collection Parameter(313) • Replace Conditional Dispatcher with Command(191) • Move Accumulation to Visitor(320) • Replace Conditional Logic with Strategy(129) • Oddball Solution • Unify Interfaces with Adapter(247) • Primitive Obsession • Replace Type Code with Class(286) • Replace Sate-Altering Conditionals with State(166) • Replace Conditional Logic with Strategy(129) • Replace Implicit Tree with Composite(178) • Replace Implicit Language with Interpreter(269) • Move Embellishment to Decorator(144) • Encapsulate Composite with Builder(96) • Solution Sprawl • Move Creation Knowledge to Factory(68) • Switch Statements • Replace Conditional Dispatcher with Command(191) • Move Accumulation to Visitor(320)

  18. 리팩터링 형식 • States Pattern Name and Intent • Gives an application example • Discusses motivation • Benefits and Liabilities • Mechanics • Specific things to do • Presents detailed example

  19. Replace Constructors with Creation Methods

  20. 요약 • 어떤 클래스의 인스턴스를 생성할 때 그것이 제공하는 여러 생성자 중 어떤 것을 호출해야 할지 결정하기 어렵다. • 인스턴스를 생성해 리턴하는 생성 메서드로 각 생성자를 대체하여 그 용도가 명확하게 드러나도록 한다.

  21. 동기 • 생성자가 많으면 그 자체만 보고 용도를 파악하기 어렵다. • 생성자가 많을 수록, 프로그래머가 잘못 선택할 확률도 높아진다. • 어떤 생성자를 사용할지 고민하면 개발이 늦어진다. • 생성 메서드를 사용해서 이러한 문제점을 제거한다. • Extract Class , Extract Subclass 리팩터링을 먼저 고려.

  22. 장점과 단점 + 상태 전이 로직을 줄이거나 없앨 수 있다. + 복잡한 상태 전이 로직이 단순해 진다. + 상태 전이 로직을 더 쉽게 알아볼 수 있게 된다. - 원래의 상태 전이 로직이 이해하기에 별로 복잡하지 않다면, 괜히 디자인만 복잡하게 만드는 것이다.

  23. 절차 • ….

  24. 예제 public class Loan { public Load( double commitment, intriskRating, Date maturity) { this(commitment, 0.00, riskRating, maturity, null); } public Load( double commitment, intriskRating, Date maturity, Date expiry ) { this(commitment, 0.00, riskRating, maturity, expiry ); } public Load( double commitment, double outstanding, intriskRating, Date maturity, Date expiry) { this(null, commitment, outstanding, riskRating, maturity, expiry ); } public Load( CapitalStrategycapitalStrategy, double commitment, intriskRating, Date maturity, Date expiry) { this( capitalStrategy, commitment, 0.0, riskRating, maturity, expiry ); } public Load( CapitalStrategycapitalStrategy, double commitment, double outstanding, intriskRating,Datematurity, Date expiry ) { this.commitment = commitment; this.outstanding = outstanding; this.riskRating = riskRating; this.maturity = maturity; this.expiry = expiry; this.capitalStrategy = captialStrategy; if(capitalStrategy == null ) { if( expiry == null ) this.capitalStrategy = new CapitalStrategyTermLoan(); else if( maturity == null ) this.capitalStrategy = new CapitalStrategyRevolver(); else this.capitalStrategy = new CapitalStrategyRCTL(); } } }

  25. 1. Load 생성자를 하나 고르고 이 생성자를 사용하는 클라이언트 코드를 찾는다. public class CapitalCalculationTests... public void testTermLoanNoPayments() { ... Loan temLoadn = new Loan(commitment, riskRating, maturity); ... }

  26. 2. Extract Method 리팩터링을 적용해 CreateTermLoan이라는 public 메서드를 만든다. public class CapitalCalculationTests... public void testTermLoanNoPayments() { ... Loan temLoadn = new Loan(commitment, riskRating, maturity); ... } public class CapitalCalculationTests... public void testTermLoanNoPayments() { //... Loan temLoadn = createTermLoan(commitment, riskRating, maturity); //... } public Loan createTermLoan(double commitment, intriskRating, Date maturity) { return new Loan(commitment, riskRating, maturity); } Extract Method

  27. 3. Move Method 리팩터링을 적용해 생성 메서드createTermLoan()을 Loan 클래스로 옮긴다. public class CapitalCalculationTests... public void testTermLoanNoPayments() { //... Loan temLoadn = createTermLoan(commitment, riskRating, maturity); //... } public Loan createTermLoan(double commitment, intriskRating, Date maturity) { return new Loan(commitment, riskRating, maturity); } Move Method public class Loan public static Loan createTermLoan(double commitment, intriskRating, Date maturity) { return new Loan(commitment, riskRating, maturity); }

  28. 4. 선택한 생성자를 사용하는 모든 클라이언트 코드를 수정한다. public class CapitalCalculationTests... public void testTermLoanNoPayments(){ //... Loan temLoadn = Loan.createTermLoan(commitment, riskRating, maturity); //... } }

  29. 5. 이제 선택한 생성자를 사용하는 곳은 CreateTermLoan뿐이다.Inline method 를 적용해 생성자 호출 부분을 제거한다. public class Loan public Loan(double commitment, intriskRating, Date maturity){ this(commitment, 0.00, riskRating, maturity, null) } public static Loan createTermLoan(double commitment, intriskRating, Date maturity) { return new Loan(commitment, 0.00, riskRating, maturity, null); }

  30. 6. 다른 생성자에 대해서도 1-5 과정을 반복한다.

  31. Replace Implicit Language with Interpreter • 한 클래스 내의 여러 메서드에서 일종의 묵시적 언어를 이루는 요소들을 조합하고 있다면. • 그 묵시적 언어의 요소들을 각각의 클래스로 정의하고 그 객체의 조합을 통해 해석 가능한 수식을 만들어 낼 수 있도록 한다.

  32. 묵시적 언어 • 10달러 이하의 상품을 찾아라. • 흰색이 아니고 10달러 이하인 상품을 찾아라. • 파란색이고 작으며 20달러 이하인 상품을 찾아라. ProductFinder… public List byColor(..); … public List belowPriceAvoidingAColor(float price, Color color); public List byColorAndBelowPrice(Color color, float price); public List byColorSizeAndBelowPrice(…)

  33. Interpreter belowPriceAvoidingAColor… and AndSpec spec = new AndSpec( new BelowPriceSpec(price), new NotSpec( new ColorSpec(color) ) ); Price < target price not Color == target color

  34. Q&A

  35. 새해 복 많이 받으세요.

More Related