Transcript
  • Java
  • Web
  • Programming
  • Advanced
  • Week02
  • Spring Framework
  • [email protected]
  • 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

Top Related