Preview:
DESCRIPTION
Citation preview
- Java
- Web
- Programming
- Advanced
- Week02
- Spring Framework
- snatcher@nhn.com
- https://github.com/eternity-next/score-spring.git
- score-client-01
- 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
- Hidden ScoreRepository
- @Test public void starndardGrade() { Lecture lecture = new
Lecture(new StandardGrader()); String grade = lecture.grade();
assertEquals("A:1 B:1 C:1 D:0 F:2 ", grade); } assertEquals
- A:1 B:1 C:1 D:0 F:2 ?
- Solution Dependency Injection
- 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
- LectureRegistry object :Lecture object :Standard Grader object
:PassFail Grader object :HttpScore Repository object :Lecture
cache
- get Standard Grade Lecture get Pass Fail Grade Lecture
Container
- public class Score { private static LectureRegistry
lectureFactory = new LectureRegistry(); public static void
main(String [] args) { Lecture lecture = null; Scanner scanner =
new Scanner(System.in); try { System.out.print("grader? ");
switch(scanner.next()) { case "st": lecture =
lectureFactory.getStandardGradeLecture(); break; case "pf": lecture
= lectureFactory.getPassFailGradeLecture(); break; default: return;
} System.out.println(lecture.grade()); } finally { scanner.close();
} } } Score class
- Complex Object Graph, Simple API
- lecture = lectureFactory.getStandardGradeLecture(); lecture =
lectureFactory.getPassFailGradeLecture(); Dependency Lookup
- score-client-03
- Registry?
- new?
- Dependency Injection?
- ?
- Spring Registry Spring
- 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
- Scores.xml
- Application Context Application Context
- Scores.xml
- Application Context Application Context object :HttpScore
Repository httpScore Repository
- Scores.xml
- Application Context Application Context object :Standard Grader
object :PassFail Grader object :HttpScore Repository httpScore
Repository passFail Grader standard Grader
- Scores.xml
- Application Context Application Context object :Lecture object
:Standard Grader object :PassFail Grader object :HttpScore
Repository httpScore Repository passFail Grader standard Grader
standard Grade Lecture Dependency Injection
- Sores.xml
- Application Context Application Context object :Lecture object
:Standard Grader object :PassFail Grader object :HttpScore
Repository object :Lecture httpScore Repository passFail Grader
standard Grader standard Grade Lecture passFail Grade Lecture
Dependency Injection
- Load Application Context GenericXmlApplicationContext context =
new GenericXmlApplicationContext("classpath:scores.xml);
Application Context object :Lecture object :Standard Grader object
:PassFail Grader object :HttpScore Repository object :Lecture
httpScore Repository passFail Grader standard Grader standard Grade
Lecture passFail Grade Lecture
- Dependency Lookup lecture =
context.getBean("passFailGradeLecture", Lecture.class); Application
Context object :Lecture object :Standard Grader object :PassFail
Grader object :HttpScore Repository object :Lecture httpScore
Repository passFail Grader passFail Grade Lecture id class
- Dependency Injection
- Dependency Lookup
- score-client-04
- Constructor Injection Discussion public Lecture(Grader grader,
ScoreRepository scoreRepository) { this.grader = grader;
this.scoreRepository = scoreRepository; }
- Setter Injection Discussion public void setGrader(Grader
grader) { this.grader = grader; } public void
setScoreRepository(ScoreRepository scoreRepository) {
this.scoreRepository = scoreRepository; }
- Stateful vs Stateless Discussion
- Prototype & Singletone Stateful Stateless