1. 컨테이너
- 자바객체 생성-소멸, 생명주기 관리기능
2. POJO
- 상속과 오버라이딩 규칙 없이 만들어진 어디에서나 호출 사용 가능한 객체들
MemberDAO - Servlet, MAIN
3. COUPLING(결합도)
- 두개 객체 동일 메소드 존재할 때
- MAIN : LGTV or SAMSUNGTV 객체 생성 결정
- MAIN ; 객체 생성 사용 ; injection(주입)
- MAIN 클래스는 매번 소스 수정이 필요하다 = LGTV와 SamsungTV 결합도가 높다.
- 클래스와 클래스간의 의존도가 높으면 코드 수정이 복잡해진다.
- 결합도가 높은 코드는 비 효율적이다.
- Coupling 높은 경우 ; 두개 이상의 파일이 연관되었을 때 하나 파일이 변경되면
나머지 하나의 파일을 같이 변경하는 것이다.
- 23가지 주요 디자인 패턴 중에서 하나인 팩토리 패턴을 사용했다.
public class SamsungTV {
public void powerOn(){
System.out.println("LG TV 켜기");
}
public void powerOff(){
System.out.println("LG TV 끄기");
}
public void volumeUp(){
System.out.println("Volume 올리기");
}
public void volumeDown(){
System.out.println("Volume 내리기");
}
}
public class LGTV {
public void powerOn(){
System.out.println("LG TV 켜기");
}
public void powerOff(){
System.out.println("LG TV 끄기");
}
public void volumeUp(){
System.out.println("Volume 올리기");
}
*/public void volumeDown(){
System.out.println("Volume 내리기");
}*/
}
public class TVUser {
public static void main(String[] args) {
LGTV lg = new LGTV();
lg.volumeDown() <-- 오류 발생
}
}
결합도가 크다. 결합도를 다소 낮추기 위해서는 아래와 같이 인터페이스를 사용한다.
package coupling;
// interface 에는 public+abstract가 생략되어있다.
public interface TV {
void powerOn();
void powerOff();
void volumeUp();
void volumeDown();
}
public class LGTV implements TV {
public void powerOn(){
System.out.println("LG TV 켜기");
}
public void powerOff(){
System.out.println("LG TV 끄기");
}
public void volumeUp(){
System.out.println("Volume 올리기");
}
public void volumeDown(){
System.out.println("Volume 내리기");
}
}
public class SamsungTV implements TV{
public void powerOn(){
System.out.println("Samsung TV 켜기");
}
public void powerOff(){
System.out.println("Samsung TV 끄기");
}
public void volumeUp(){
System.out.println("Volume 올리기");
}
public void volumeDown(){
System.out.println("Volume 내리기");
}
}
package coupling;
public class TVUser {
public static void main(String[] args) {
TV lgs = null;
if(args[0].equals("samsung")){
lgs = new SamsungTV();
}else if(args[0].equals("lg")){
lgs = new LGTV();
}
lgs.powerOff();
}
}
시스템 매개변수에서 samsung과 lg를 입력하여 결과를 확인한다.
결합도가 위 코드보다 다소 낮아졌다.
결합도를 더욱 낮추기 위해서 아래 MAIN과 TV인터페이스 사이의 코드를 추가한다.
package coupling;
public class TVFactory {
public static TV getTV(String name){
if(name.equals("samsung")){
return new SamsungTV();
}else if(name.equals("lg")){
return new LGTV();
}else{
return null;
}
}
}
package coupling;
public class TVUser {
public static void main(String[] args) {
TV lgs = TVFactory.getTV(args[0]);
lgs.powerOff();
}
}
결합도를 상당히 낮춘 예제이다.
4. 의존 주입성 (Dependency injection ; DI)
위 마지막 예제에서 TVFactory 도움을 받아 injection 하는 것을 DI 유형이라고 한다.
스프링 프레임워크를 사용하면 아래와 같다.
package coupling;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class TVUser {
public static void main(String[] args) {
BeanFactory factory = new XmlBeanFactory
(new ClassPathResource("applicationContext.xml"));
// 프로젝트 \src\*.xml == ClassPathResource
// Tv tv = new SamsungTV() <== xml 기술
TV tv = (TV)factory.getBean("tv");
tv.powerOff();
tv.powerOn();
tv.volumeDown();
tv.volumeUp();
}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="tv" class="coupling.LGTV"></bean>
</beans>
=> xml에서 bean 부분만 수정하면 의존성이 상당히 낮아진다.
xml 파일을 coupling 패키지에 넣을 경우에는 아래와 같이 수정한다.
기존 : new classPathResource("applicationContext.xml"));
수정 : new classPathResource("coupling/applicationContext.xml"));
5. IOC(Inversion Of Controll)
=> 제어 역행 ; 자바 개발자에게 필요하면 직접 생성하지 않고 spring container 주입
==> coupling(결합도)을 줄여준다.