Dependency Breaking Techniques            Working Effectively with LegacyCode                                             ...
before           after24   dependency breaking techniques
1. Adapt Parameter                                        Interface A’   Method (   A   ){     ...   }                    ...
When to use? - parameter is difficult to test. - can’t use Extract Interface on a parameter’s class.
2. Break Out Method Object  Class     longMethod A() {       …       …       …                New Class A     }           ...
When to use?- method is too large- use instance data and methods
3. Definition Completion                       Definition for       Definition          Test     Concrete Class    Concret...
When to use? - language supplies that can declare a type in on place anddefine it another.- to break dependencies in proce...
4. Encapsulate Global References    Class               New Class A     Global reference      Global reference
When to use?- to separate dependencies on global references.
5. Expose Static Method                          Class    Class                             Static Method () {            ...
When to use?- trying to test code that can’t be instantiated.
6. Extract and Override CallClass               Class               Class for test   Method ( ) {        Method ( ) {    …...
When to use?- trying to test only single method call.
7. Extract and Override Factory MethodClass                Class                   Class for testconstructor( ) {      con...
When to use?- trying to test code that creates objects in constructor.
8. Extract and Override GetterClass                Class                     Class for testconstructor( ) {      construct...
When to use?  - trying to test code that creates objects in constructor  - language doesn’t support virtual function call ...
9. Extract Implementer                Duplicated Class                 Method A() {      InterfaceClass              …    ...
When to use?- hard to naming the interface
10. Extract Interface                Interface                 virtual Method A()   Concrete ClassClass                   ...
When to use?- trying to test code that break dependency
11. Introduce Instance DelegatorClass                    Class                     Class for testStatic Method A( ) {     ...
When to use?- static method has logic that hard to test- it’s weird- 더 큰 리팩토링의 시작
12. Introduce Static SetterClass                           Class                           Class for testStatic instance  ...
When to use? - Singleton test - Protected constructor = can subclassing = 구리다 - singleton을 코드로 강제하는 것보다는 팀원들이모두 이해하는게 더 중요...
13. Link Substitution                        Global reference for test                          Call history              ...
When to use?- to break dependencies in procedural language like C.
14. Parameterize ConstructorClass                 Class                Class for testconstructor( ) {      constructor( ) ...
When to use?- to separate the object that created in constructor.has dependencies on parameter’s class.but it’s a small co...
15. Parameterize Method    Class                 Class    Method( ) {           Method( A ) {      …                     …...
When to use? -to separate the object that created in method.dependency issue?Extract and Override Factory Method is altern...
16. Primitivize ParameterClass          Class                     TestClassMethod ( ) {   Method ( ) {              TEST( ...
When to use?- work to get a class under test is too large.- what the…
17. Pull Up Feature                                  New Abstract Class                                        Method A( )...
When to use?- to test just one method that clustered with other methods.
18. Push Down Dependency                     Abstract ClassClass                       Method A( ) { Method A( ) {        ...
When to use? - dependencies are pervasive like drawing UI.
19. Replace Function with Function Pointer   Method main( ) {   Method main( ) {     …                  …     A();        ...
When to use?- to break dependencies in procedural language like C.Different points of view- horribly unsafe VS useful tool
20. Replace Global Reference with GetterClass                  Class                    Class for test Global references A...
When to use?- separate dependencies on global references
21. Subclass and Override Method  Class                 Class  private Method A(){   protected Method A(){    …           ...
When to use? - break dependencies in object-oriented language.Many of the other dependency-breaking techniquesare variatio...
22. Supersede Instance Variable Class              Class                    Class for test variable           variable con...
When to use? - separate objects that created in constructor. - language disallows overrides of virtual function callsin co...
23. Template Redefinition                                        generics   Method (   A   ){     ...   }                 ...
When to use? - language supplies generics and a way of aliasing types.
24. Text Redefinition                        TestClass      Class                Class                           def Metho...
When to use?- break dependencies in interpreted language like Ruby.
전체 정리하면서 느낀 점- 억지스러운 면이 자주 보인다.- dependency 는 깨질지 몰라도 Readability는 더 낮아진다.- 코드가 잘못 사용될 수 있으니 개발자가 더 주의 깊게 살펴봐야 한다.- 아무래도 L...
Reference            레거시코드 활용 전략            http://www.yes24.com/24/goods/3092523
감사합니다
Upcoming SlideShare
Loading in...5
×

Dependency Breaking Techniques

4,028

Published on

LegacyCode

아꿈사 스터디 발표자료.

Published in: Technology
1 Comment
3 Likes
Statistics
Notes
No Downloads
Views
Total Views
4,028
On Slideshare
0
From Embeds
0
Number of Embeds
10
Actions
Shares
0
Downloads
0
Comments
1
Likes
3
Embeds 0
No embeds

No notes for slide

Transcript of "Dependency Breaking Techniques"

  1. 1. Dependency Breaking Techniques Working Effectively with LegacyCode Ver 1.0 아키텍트를 꿈꾸는 사람들 cafe.naver.com/architect1 현수명 soomong.net #soomong
  2. 2. before after24 dependency breaking techniques
  3. 3. 1. Adapt Parameter Interface A’ Method ( A ){ ... } Concrete A’ Concrete A’ for production for test
  4. 4. When to use? - parameter is difficult to test. - can’t use Extract Interface on a parameter’s class.
  5. 5. 2. Break Out Method Object Class longMethod A() { … … … New Class A } longMethod () { … … … }
  6. 6. When to use?- method is too large- use instance data and methods
  7. 7. 3. Definition Completion Definition for Definition Test Concrete Class Concrete Class
  8. 8. When to use? - language supplies that can declare a type in on place anddefine it another.- to break dependencies in procedural language like C.
  9. 9. 4. Encapsulate Global References Class New Class A Global reference Global reference
  10. 10. When to use?- to separate dependencies on global references.
  11. 11. 5. Expose Static Method Class Class Static Method () { … Method () { } … }
  12. 12. When to use?- trying to test code that can’t be instantiated.
  13. 13. 6. Extract and Override CallClass Class Class for test Method ( ) { Method ( ) { … … logic call A(); … … } } @Override Method A ( ) { Method A( ) { logic test logic } }
  14. 14. When to use?- trying to test only single method call.
  15. 15. 7. Extract and Override Factory MethodClass Class Class for testconstructor( ) { constructor( ) { … … object = new A() object = call A(); … …} } @Override Factory method A(){ Factory method A(){ return new A() … } }
  16. 16. When to use?- trying to test code that creates objects in constructor.
  17. 17. 8. Extract and Override GetterClass Class Class for testconstructor( ) { constructor( ) { … … object = New A() object = null; … …} } @Overrideobject Getter Method getA(){ Getter Method getA(){ if A is null … object return new A(); } return A; } getA() getA() Lazy initialize
  18. 18. When to use? - trying to test code that creates objects in constructor - language doesn’t support virtual function call in a derived classfrom base class’s constructor
  19. 19. 9. Extract Implementer Duplicated Class Method A() { InterfaceClass … } virtual Method A() Method A() { … Method B() { virtual Method B() } … } Method B() { … }
  20. 20. When to use?- hard to naming the interface
  21. 21. 10. Extract Interface Interface virtual Method A() Concrete ClassClass Method A() { virtual Method B() Method A() { … … } } Method A() { Method B() { … … } }
  22. 22. When to use?- trying to test code that break dependency
  23. 23. 11. Introduce Instance DelegatorClass Class Class for testStatic Method A( ) { Static Method A( ) { … …} } @Override Method A’(){ Method A’(){ Class.A() A(); … } } Class.A() instance.A’() instance.A’()
  24. 24. When to use?- static method has logic that hard to test- it’s weird- 더 큰 리팩토링의 시작
  25. 25. 12. Introduce Static SetterClass Class Class for testStatic instance Static instanceprivate constructor( ) { protected constructor( ) {} }Static Method getInst(){ Static Method getInst(){ if instance is null if instance is null instance = new Class(); instance = new Class(); return instance; return instance;} } @Override Method setInstance(…) { Method setInstance(…) { instance = … test logic } }
  26. 26. When to use? - Singleton test - Protected constructor = can subclassing = 구리다 - singleton을 코드로 강제하는 것보다는 팀원들이모두 이해하는게 더 중요하다?
  27. 27. 13. Link Substitution Global reference for test Call history Value history Method A() { … } Method A() { record call history record value history … }
  28. 28. When to use?- to break dependencies in procedural language like C.
  29. 29. 14. Parameterize ConstructorClass Class Class for testconstructor( ) { constructor( ) { … this( new A() ); object = new A(); } …} constructor( A ) { constructor( A ) { … … object = A; object = test; … … } }
  30. 30. When to use?- to separate the object that created in constructor.has dependencies on parameter’s class.but it’s a small concern.
  31. 31. 15. Parameterize Method Class Class Method( ) { Method( A ) { … … object = new A(); object = A; … … } }
  32. 32. When to use? -to separate the object that created in method.dependency issue?Extract and Override Factory Method is alternative way.
  33. 33. 16. Primitivize ParameterClass Class TestClassMethod ( ) { Method ( ) { TEST( ) { … … … logic call free function(); call free function(); … … }} } free function( ) { logic }
  34. 34. When to use?- work to get a class under test is too large.- what the…
  35. 35. 17. Pull Up Feature New Abstract Class Method A( ) { … } abstract Method B abstract Method C Class Method A( ) { … Class Class for test } Method B( ) { TEST( ) { Method B( ) { … CHECK(A()); … } } } Method C( ) { Method C( ) { … … } }
  36. 36. When to use?- to test just one method that clustered with other methods.
  37. 37. 18. Push Down Dependency Abstract ClassClass Method A( ) { Method A( ) { … … } } Method B( ) { Method B( ) { … … } } abstract drawUI()Method drawUI( ) { …} New Concrete Class Concrete Class for test Method drawUI( ) { Method drawUI( ) { … // do nothing } }
  38. 38. When to use? - dependencies are pervasive like drawing UI.
  39. 39. 19. Replace Function with Function Pointer Method main( ) { Method main( ) { … … A(); *pointer … … } } *Method testA( ) { test logic } Method A( ) { … } *Method A( ) { … }
  40. 40. When to use?- to break dependencies in procedural language like C.Different points of view- horribly unsafe VS useful tool
  41. 41. 20. Replace Global Reference with GetterClass Class Class for test Global references A Global references AA getA A getA @Override Getter Method getA() { Getter Method getA() { return A; … } }
  42. 42. When to use?- separate dependencies on global references
  43. 43. 21. Subclass and Override Method Class Class private Method A(){ protected Method A(){ … … } } subClass for test @Override protected Method A(){ … }
  44. 44. When to use? - break dependencies in object-oriented language.Many of the other dependency-breaking techniquesare variations on it.
  45. 45. 22. Supersede Instance Variable Class Class Class for test variable variable constructor( ) { constructor( ) { variable; variable; } } @Override supersedeVariable(A) { supersedeVariable(A) { variable = A; … } }
  46. 46. When to use? - separate objects that created in constructor. - language disallows overrides of virtual function callsin constructors.Use uncommon prefix : supersede개발자들이 잘못 사용할지도 모르니잘 모르는 uncommon 한 단어를 prefix 로 사용하자??
  47. 47. 23. Template Redefinition generics Method ( A ){ ... } Concrete type Concrete type for production for test
  48. 48. When to use? - language supplies generics and a way of aliasing types.
  49. 49. 24. Text Redefinition TestClass Class Class def Method A() def Method A() end … logic … end TEST( ) { … test Class }
  50. 50. When to use?- break dependencies in interpreted language like Ruby.
  51. 51. 전체 정리하면서 느낀 점- 억지스러운 면이 자주 보인다.- dependency 는 깨질지 몰라도 Readability는 더 낮아진다.- 코드가 잘못 사용될 수 있으니 개발자가 더 주의 깊게 살펴봐야 한다.- 아무래도 LegacyCode 와의 싸움이 힘겹긴 한가보다. 이해하자.- 억지스럽고 지저분한 방법일지라도 대안이 없다면 그게 바로 최선의 방법이다.- 원문이 훨씬 보기 쉽다. (번역 X)
  52. 52. Reference 레거시코드 활용 전략 http://www.yes24.com/24/goods/3092523
  53. 53. 감사합니다

×