카테고리 보관물: OOAD

리액터(Reactor) 패턴의 성능 향상 방안..

리액터(Reactor) 패턴을 사용해서 자바 네트워크 서버를 개발하다 보면, 동접을 2000 이상 붙여보면 성능저하를 확인할 수 있다. 그래서 리액터를 마스터-슬레이브(Master-Slave)의 구조로 개선하고, 슬레이브 리액터의 개수를 CPU 개수만큼 만들어서 성능을 개선할 수 있다. 아래는 이 구조를 쉽게 알수 있는 그림이다.^^

DI(Dependency Injection)에 대해서..

객체가 스스로 참조하는 객체를 생성하지 않고, 외부 환경(컨테이너)에서 삽입 되는 형태를 DI(Dependency Injection)라고 한다. 그리고, DI를 구현하는 방법은 2가지가 있다.

1. 생성자(Constructor) 방식

public class Shop {   
  private final StockManager stockManager;   
  private final String shopZipCode;   
  public Shop(StockManager stockManager, String shopZipCode) {   
       this.stockManager = stockManager;   
       this.shopZipCode = shopZipCode;   
  }   
}

2. 세터(Setter) 방식

public class Shop {   
  StockManager stockManager;   
  String shopZipCode;   
  /**  
  * @service name="StockManager"       
  */  
  public void setStockManager(StockManager stockManager) {   
      this.stockManager = stockManager;   
  }   
  /**  
  * @config name="shopZipCode"       
  */  
  public void setStockManager(String shopZipCode) {   
      this.shopZipCode= shopZipCode;   
  }   
  // TODO - Joe - how does setter injector do config ? Same way?   
  public void initialize() {   
      // all setXXXs are now done  
  }   
} 

POSA 1 – 마스터-슬레이브(Master-Slave) 패턴

마스터-슬레이브(Master-Slave) 패턴은 마스터(Master)가 슬레이브(Slave)에게 작업을 분산하고, 슬레이브가 처리한 결과로 최종 결과를 계산하는 패턴이다. 즉, 마스터는 작업을 쪼개고, 슬레이브에게 쪼갠 작업을 분배하고, 결과를 계산하는 역할을 한다. 그리고 슬레이브는 마스터의 작업 요청을 처리하고, 결과를 리턴한다.

그래서 위 패턴의 형태로 간단한 코드를 작성해 보자. 예제는 1부터 10까지의 factorial을 10개의 작업(Job)으로 나누고, 나눠진 작업의 결과를 마스터가 더해서 마지막 결과를 보여주는 예제이다.

아래의 MSClient는 클라이언트와 마스터 역할을 담당한다. JobThread는 슬레이브 역할을 담당한다.

– MSClient.java

import java.util.List;
import java.util.ArrayList;
import java.util.concurrent.Future;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ExecutionException;
import java.math.BigInteger;

public class MSClient {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
           
        ArrayList jobArray = new ArrayList();
        ExecutorService executor =  Executors.newFixedThreadPool(10);
           
        for (int i = 1; i <= 10; i++) {
            jobArray.add(new JobThread(i));
        }
       
        List<Future> allResults = null;
       
        long totalSum = 0;
       
        try {
            allResults = executor.invokeAll(jobArray);
                         
            for(int i=0; i < allResults.size(); i++) {
                totalSum += allResults.get(i).get().longValue();
                System.out.println((i+1) + “! is ” + allResults.get(i).get());
            }
           
            System.out.println(“Total Value is ” + totalSum);

        } catch (InterruptedException e) {
            System.out.println(“Interrupted”);
        } catch (ExecutionException e) {
            System.out.println( “Execution exception”);
        }
       
        executor.shutdown();
    }
}

– JobThread.java

import java.util.concurrent.Callable;
import java.math.BigInteger;

public class JobThread implements Callable {
    //
    private int min = 1;
    //
    private int value = 0;
   
    public JobThread(int value) {
        this.value = value;
    }
   
    @Override
    public BigInteger call() throws Exception {
       
        BigInteger fac = BigInteger.valueOf(this.min);
       
        for (int i = 1; i <= this.value; i++)
            fac = fac.multiply(BigInteger.valueOf(i));
   
        return fac;
    }
}

POSA 1 – Whole-Part Pattern

Whole-Part 패턴은 Whole 객체를 구성하는 Part 객체들을 모으고, 그 객체들간의 협력을 통해서 기능을 구현하는 패턴입니다. 그리고, Whole 객체가 클라이언트에 인터페이스를 제공하고 Part 객체들은 Whole객체만을 통해서 접근을 하게 만들어 주는 형태입니다. GOF의 Composite 패턴과 동일한 느낌이네요.. ^^;;

제가 생각하는 내용을 아래의 형태별로 간단하게 코드로 끄적여 봅니다.
아래의 WPClient는 Car라는 Whole 객체를 통해서 앞으로 뒤로 기능을 테스트 합니다.
혹시 코드보시고, 틀렸다고 생각이 되시는 부분이 있으면 답글로 끄적여 주시면 감사하겠습니다.

WPClient.java

package client;

import wp.Car;
import wp.part.*;

public class WPClient {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Car car = new Car();
        car.setEngine(new Engine());
        car.setLight(new Light());
        car.setWheel(new Wheels());
       
        car.keyPress(true);
        car.forward();
        car.backward();
    }
}

Car.java

package wp;

import wp.part.*;

public class Car {
    //
    private Wheels wheel;
    //
    private Engine engine;
    //
    private Light light;
   
    public Wheels getWheel() {
        return wheel;
    }
    public void setWheel(Wheels wheel) {
        this.wheel = wheel;
    }
    public Engine getEngine() {
        return engine;
    }
    public void setEngine(Engine engine) {
        this.engine = engine;
    }
    public Light getLight() {
        return light;
    }
    public void setLight(Light light) {
        this.light = light;
    }
   
    public void keyPress(boolean isNight) {
        boolean check = false;
       
        check = this.engine.start();
        if(isNight) {   
            check = this.light.start();
        }
    }

    public void forward() {
        boolean check = this.wheel.forward();
       
    }
   
    public void backward() {
        boolean check = this.wheel.backward();
    }
}

Engine.java

package wp.part;

public class Engine {
   
    private boolean isStarted;
   
    public boolean start() {
        System.out.println(“Engine start Ok”);
        this.isStarted = true;
        return true;
    }
   
    public void stop() {
        this.isStarted = false;
    }
}

Light.java

package wp.part;

public class Light {
    private boolean isLighting;
   
    public boolean start() {
        System.out.println(“Light start Ok”);
        this.isLighting = true;
        return true;
    }
   
    public void stop() {
        this.isLighting = false;
    }
}

Wheels.java

package wp.part;

public class Wheels {

    private boolean isWheeling;
   
    public boolean forward() {
        System.out.println(“앞으로 굴러갑니다.”);
        this.isWheeling = true;
        return true;
    }
   
    public boolean backward() {
        System.out.println(“뒤로 굴러갑니다.”);
        this.isWheeling = true;
        return true;
    }
   
    public void stop() {
        this.isWheeling = false;
    }
}

* reference
http://www.devpia.com/NET2/EvaCast/Lecture/?cu=view&r=128
http://wiki.javajigi.net/display/SWD/Whole-Part+Design+Pattern