2009년 5월 15일 금요일

IoC (Inversion of Control) 컨테이너에 대한 정리 2

이미 작년에 정리를 했었는데
 
 
인터넷에 더 좋은 예제들이 있어서 좀 퍼다 놓습니다.
아래 글의 출처는 : http://dnene.com/archives/3
 
일단 비즈니스 로직을 간략이 기술하면
a. Locate the airline agency
b. Book the airline tickets
c. Locate the cab agency
d. Request a cab for a prespecified time
 
위 네 가지일때 일반적인 기본 코드가 아래와 같다고 해보죠.
 

public class TripPlanner()
{
        private AirlineAgency airlineAgency;
        private CabAgency cabAgency;

        public TripPlanner()
        {
        }

        public void setAirlineAgency(AirlineAgency airlineAgency)
        {
                this.airlineAgency = airlineAgency;
        }

        public void setCabAgency(CabAgency cabAgency)
        {
                this.cabAgency = cabAgency;
        }

        public void bookTrip(TripParameters tripParameters)
        {
                FlightSchedule flightchedule = airlineAgency.bookTickets(
                        tripParameters.getDestination(),
                        tripParameters.getRequestedArrivalTime());

                // Request a cab
                // You want to have a cab 90 minutes before the flight departure time
                Date cabTime = cabAgency.requestCab(
                        tripParameters.getStartingAddress(),
                        flightSchedule.getFlightDepartureTime(),
                        90);

                // log outputs — included here for brevity of example
                System.out.println(“Your flight is scheduled to depart at “ +
                        flightSchedule.getFlightDepartureTime());
                System.out.println(“A cab is scheduled to pick you up at “ +
                        cabSchedule.getPickupTime());
        }
}
 
 
이제 이걸 IoC로 변경하면 어찌 되는지
 
우선 Spring Framework 의 경우입니다.
 
public class TripPlanner()
{
        private AirlineAgency airlineAgency;
        private CabAgency cabAgency;

        public TripPlanner()
        {
        }

        public void setAirlineAgency(AirlineAgency airlineAgency)
        {
                this.airlineAgency = airlineAgency;
        }

        public void setCabAgency(CabAgency cabAgency)
        {
                this.cabAgency = cabAgency;
        }

        public void bookTrip(TripParameters tripParameters)
        {
                FlightSchedule flightchedule = airlineAgency.bookTickets(
                        tripParameters.getDestination(),
                        tripParameters.getRequestedArrivalTime());

                // Request a cab
                // You want to have a cab 90 minutes before the flight departure time
                Date cabTime = cabAgency.requestCab(
                        tripParameters.getStartingAddress(),
                        flightSchedule.getFlightDepartureTime(),
                        90);

                // log outputs — included here for brevity of example
                System.out.println(“Your flight is scheduled to depart at “ +
                        flightSchedule.getFlightDepartureTime());
                System.out.println(“A cab is scheduled to pick you up at “ +
                        cabSchedule.getPickupTime());
        }
}
 
코드는 위와 같이 바뀌고 설정을 아래와 같이 해줘야죠.
 
<beans>
        <bean id=“airlineAgency” class=“com.example.agencies.MyAirlineAgency”/>

        <bean id=“cabAgency” class=“com.example.agencies.MyCabAgency”/>

        <bean id=“tripPlanner” class=“com.example.agencies.TripPlanner”>
                <property name=“airlineAgency”>
                        <ref local=“airlineAgency”/>
                </property>
                <property name=“cabAgency”>
                        <ref local=“cabAgency”/>
                </property>
        </bean>
</beans>
 
 
 
Picocontainer 를 IoC 컨테이너로 택했다면
 
public class TripPlanner()
public class TripPlanner()
{
        private AirlineAgency airlineAgency;
        private CabAgency cabAgency;

        public TripPlanner(AirlineAgency airlineAgency, CabAgency cabAgency)
        {
                this.airlineAgency = airlineAgency;
                this.cabAgency = cabAgency;
        }

        // Setters are no longer required (unless other parts of your code need them)

        // No change to planTrip()
        // …..
        // …..
}
 
 
코드는 위와 같이 바뀌고 Pico는 XML로 설정을 못한다고 하니(아마 조합으로 쓰이도록 고려해서 인듯 합니다.) 아래와 같이 별도의 관리되는 객체 즉 스프링에서의 빈을 등록하는 코드 작성이 필요합니다.
 
// Instantiate pico container
MutablePicoContainer pico = new DefaultPicoContainer();

// register implementations
pico.registerComponentImplementation(MyAirlineAgency.class);
pico.registerComponentImplementation(MyCabAgency.class);
pico.registerComponentImplementation(MyTripPlanner.class);

//Obtain reference to trip planner using pico
TripPlanner planner = (TripPlanner) pico.getComponentInstance(TripPlanner.class);
 
오픈 심포니의 xwork 을 선택하는 경우는 코드가 아래와 같이 됩니다.
 
// The code that does the "wiring up" of dependencies
// Get a reference to the component manager
public static final String COMPONENT_MANAGER =
          “com.opensymphony.xwork.interceptor.component.ComponentManager”;
ComponentManager cm = (ComponentManager)
          ActionContext.getContext().get(COMPONENT_MANAGER);

// Register the enabler interfaces
cm.addEnabler(AirlineAgency.class, AirlineAgencyAware.class);
cm.addEnabler(CabAgency.class, CabAgencyAware.class);

// Register the implementations
cm.initializeObject(new MyAirlineAgency());
cm.initializeObject(new MyCabAgency());


public AirlineAgencyAware
{
        public void setAirlineAgency(AirlineAgency airlineAgency);
}

public CabAgencyAware
{
        public  void setCabAgency(CabAgency cabAgency);
}

public class planTrip extends ActionSupport implements AirlineAgencyAware, CabAgencyAware
{
        private AirlineAgency airlineAgency;
        private CabAgency cabAgency;

        public void setAirlineAgency(AirlineAgency airlineAgency)
        {
                this.airlineAgency = airlineAgency;
        }

        public void setCabAgency(CabAgency cabAgency)
        {
                this.cabAgency = cabAgency;
        }

        public String execute()
        {
                // …. implement the trip planning functionality
                // the references to the agency objects will already have
                // been set by the time the code execution reaches here.
                // ….
        }
}
 
C++ 처럼 자바 코드 바깥에.. 문장이 있는데
코드를 발췌해서 그런 것인지 XWork가 그런 문법을 지원하는지는 모르겠네요.@@
아무튼 XWork은 WebWork과 연동이 기본적으로 고려되어 있어서
순수 IoC라기 보다.. 커맨드 패턴으로 사용되는 환경에서의 IoC로 만들어진 듯 합니다.

댓글 없음:

댓글 쓰기