class Lecture Class StandardGrader Class PassFailGrader
interface Grader Dependency Use Client Dependency Use Create
Dependency inject Dependency
class Lecture Class StandardGrader Class PassFailGrader
interface GraderUse Client Use Create inject class
ScoreRepositoryUse
class Lecture interface Grader class ScoreRepository Score
Server 2) HTTP 1) score 3) JSON 4) score
public class ScoreRepository { private String url; private
HttpClient client; public ScoreRepository() { this.url =
http://localhost:3000/scores this.client = new HttpClient( new
MultiThreadedHttpConnectionManager()); } public int [] getScores()
{ GetMethod get = new GetMethod(url); try { if
(client.executeMethod(get) == HttpStatus.SC_OK) { return new
Gson().fromJson(get.getResponseBodyAsString(), int [].class); }
else { return new int [0]; } } catch (Exception e) { throw new
RuntimeException(e); } finally { get.releaseConnection(); } } }
ScoreRepository
public class Lecture { private ScoreRepository scoreRepository;
private Grader grader; public Lecture(Grader grader) { this.grader
= grader; this.scoreRepository = new ScoreRepository(); } public
String grade() { return grader.grade(scoreRepository.getScores());
} } Lecture
Problem Testability
Transitive Dependency
Hidden Dependency
Transitive Dependency
B CA Object A
Object C
Object B
Object A
Object B
depends on
Object C
Object B
depends on
Object A
Object C
depends on
class Lecture interface Grader class ScoreRepository Score
Server LectureTest Transitive Dependency
LectureTest
Score Server
depends on
class Lecture interface Grader class ScoreRepository Score
Server LectureTest Server Down
LectureTest
Score Server
depends on
public class Lecture { private ScoreRepository scoreRepository;
private Grader grader; public Lecture(Grader grader) { this.grader
= grader; this.scoreRepository = new ScoreRepository(); } public
String grade() { return grader.grade(scoreRepository.getScores());
} } Lecture
Tight Coupling
class Lecture interface Grader class ScoreRepository Score
Server LectureTest Test Fail
LectureTest
Score Server
depends on
public class Lecture { private ScoreRepository scoreRepository;
private Grader grader; public Lecture(Grader grader) { this.grader
= grader; this.scoreRepository = new ScoreRepository(); } public
String grade() { return grader.grade(scoreRepository.getScores());
} } Hidden Dependency
class Lecture interface Grader class ScoreRepository Score
Server LectureTest Transitive Dependency
LectureTest
Score Server
depends on
class Lecture interface Grader class HttpScore Repository Score
Server LectureTest Dependency Breaking
LectureTest
Score Server
depends on
interface ScoreRepository
class Lecture interface Grader class HttpScore Repository Score
Server LectureTest Dependency Breaking
LectureTest
Score Server
depends on
interface ScoreRepository
class Lecture interface Grader class HttpScore Repository Score
Server LectureTest Testable
LectureTest
Score Server
depends on
interface ScoreRepository
public class Lecture { private ScoreRepository scoreRepository;
private Grader grader; public Lecture(Grader grader) { this.grader
= grader; this.scoreRepository = new ScoreRepository(); } public
String grade() { return grader.grade(scoreRepository.getScores());
} } Tight Coupling &
Hidden Dependency
public class Lecture { private ScoreRepository scoreRepository;
private Grader grader; public Lecture(Grader grader,
ScoreRepository scoreRepository) { this.grader = grader;
this.scoreRepository = scoreRepository; } Loose Coupling &
Explicit Dependency
Mock
{50,20,70,80,90} =>A:1 B:1 C:1 D:0 F:2
@RunWith(MockitoJUnitRunner.class) public class LectureTest {
@Mock private ScoreRepository repository; @Test public void
starndardGrade() { when(repository.getScores()) .thenReturn(new int
[] {50,20,70,80,90}); Lecture lecture = new Lecture(new
StandardGrader(), repository); String grade = lecture.grade();
assertEquals("A:1 B:1 C:1 D:0 F:2 ", grade); }
score-client-02
lecture = new Lecture(new StandardGrader(), new
HttpScoreRepository()); lecture = new Lecture(new PassFailGrader(),
new HttpScoreRepository()); Loose Coupling => Complex Object
Graph
Registry = Application Context Dependency Injection Framework
IoC Container
class Lecture class Standard Grader class PassFail Grader class
HttpScore Repository class Lecture class Lecture class Standard
Grader class HttpScore Repository class PassFail Grader Class
Configuration Metadata object :Lecture object :Standard Grader
object :PassFail Grader object :HttpScore Repository object
:Lecture Registry
class Lecture class Standard Grader class PassFail Grader class
HttpScore Repository class Lecture class Lecture class Standard
Grader class HttpScore Repository class PassFail Grader Class
Configuration Metadata object :Lecture object :Standard Grader
object :PassFail Grader object :HttpScore Repository object
:Lecture Application Context Registry
Refactoring
class Lecture class Standard Grader class PassFail Grader class
HttpScore Repository class Lecture Configuration Metadata object
:Lecture object :Standard Grader object :PassFail Grader object
:HttpScore Repository object :Lecture Application Context XML
Spring GenericXml ApplicationContext
class Lecture class Standard Grader class PassFail Grader class
HttpScore Repository class Lecture Configuration Metadata XML