태그 보관물: posa 1

POSA 1 – Master-Slave Pattern

Master-Slave Pattern은 Master가 Slave에게 작업을 분산하고, Slave를 통해서 받은 결과를 통해서 최종 결과를 계산해 내는 패턴이라고 하네요.. 따라서, Master는 작업을 쪼개고, Slaver에게 분배하고, 결과를 계산하는 역할을 할 것이고, Slave는 Master의 작업요청을 처리해서 결과를 리턴하면 되겠네요..

제가 생각하는 내용을 아래의 형태별로 간단하게 코드로 끄적여 봅니다.
예는 1부터 10까지의 factorial을 10개의 Job으로 나누고, 그것을 Master가 더하기를 합니다.
아래의 MSClient는 Client와 Master의 역할을 담당하게 되고, JobThread는 Slave의 역할을 담당합니다.
혹시 코드보시고, 틀렸다고 생각이 되시는 부분이 있으면 답글로 끄적여 주시면 감사하겠습니다.

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<JobThread> jobArray = new ArrayList<JobThread>();
        ExecutorService executor =  Executors.newFixedThreadPool(10);
           
        for (int i = 1; i <= 10; i++) {
            jobArray.add(new JobThread(i));
        }
       
        List<Future<BigInteger>> 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<BigInteger> {
    //
    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;
    }
}

* reference
http://www.devpia.com/NET2/EvaCast/Lecture/?cu=view&r=105

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

POSA 1 – Presentation Abstraction Control Pattern

Presentation Abstraction Control Pattern은 계층 형태의 시스템에서 각 단계별로 Agent를 가지고, Agent들이 계층적(상,하)으로 협력을 하는 구조가 필요할 때 사용할 수 있는 패턴이라고 하네요.. 각 Agent는 계층의 레벨에 맞는 기능을 담당합니다. 그리고 각 Agent는 Presentation, Abstraction, Control을 가질 수 있습니다.

제가 생각하는 내용을 아래의 형태별로 간단하게 코드로 끄적여 봅니다.
아래의 TopAgent는 데이타를 가지고 있고, InterMediateAgent는 mediate 기능을 담당하고 실제로 뷰는 BottomAgent를 통해서 구현을 합니다. 그리고, BottomAgent는 view()는 인터페이스로 뽑고, setter, getter 메쏘드는 Abstract Class를 통해서 여러개의 BottomAgent를 구현하면 좋을듯 합니다.


혹시 코드보시고, 틀렸다고 생각이 되시는 부분이 있으면 답글로 끄적여 주시면 감사하겠습니다

PACClient.java


public class PACClient {

 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  
  pac.TopAgent tAgent = new pac.TopAgent();
  pac.inter.InterMediateAgent interAgent = new pac.inter.InterMediateAgent();
  pac.bottom.BottomAgent bAgent = new pac.bottom.BottomAgent();
  
  interAgent.setTopAgent(tAgent);
  bAgent.setIntermediateAgent(interAgent);
  interAgent.setBottomAgent(bAgent);
  
  interAgent.sendMsg();
 }
}


TopAgent.java



package pac;


import pac.inter.InterMediateAgent;


public class TopAgent {
 //
 private InterMediateAgent intermediateAgent = null;
 
 private String data = null;
 
 //
 public InterMediateAgent getIntermediateAgent() {
  return intermediateAgent;
 }


 //
 public void setIntermediateAgent(InterMediateAgent agent ) {
  intermediateAgent = agent;
 }
 
 @SuppressWarnings(“deprecation”)
 public String getData() {
  this.data = “loading data ”
   + new java.util.Date().getYear() +”, ”
   + new java.util.Date().getMonth() +”, “
   + new java.util.Date().getDay() +”, “
   + new java.util.Date().getHours() +”, “
   + new java.util.Date().getMinutes() +”, “
   + new java.util.Date().getSeconds();
  
  return this.data;
 }


 //
 public void setData(String data) {
  this.data = data;
 }
}




InterMediateAgent.java


package pac.inter;

import pac.TopAgent;
import pac.bottom.BottomAgent;


public class InterMediateAgent {
 //
 private TopAgent topAgent = null;


 //
 private BottomAgent bottomAgent = null;
 
 //
 public TopAgent getTopAgent(){
  return topAgent;
 }


 //
 public void setTopAgent(TopAgent agent){
  topAgent = agent;
 }
 
 //
 public BottomAgent getBottomAgent(){
  return bottomAgent;
 }
 
 //
 public void setBottomAgent(BottomAgent agent){
  bottomAgent = agent;
 }
 
 //
 public String getData() {
  return this.topAgent.getData();
 }
 
 //
 public void SetData(String data) {
  this.topAgent.setData(data);
 }
 
 // template method가 되도 되겠넹..
 public void sendMsg() {
  this.bottomAgent.view();
 }


}


BottomAgent.java



package pac.bottom;


import pac.inter.InterMediateAgent;


public class BottomAgent { 
 //
 private InterMediateAgent interAgent = null;
 
 //
 private Abstraction abs = null;


 //
 private Presentation pre = null;
 
 //
 public BottomAgent() {
  abs = new Abstraction();
  pre = new Presentation();
 }
 
 //
 public InterMediateAgent getIntermediateAgent() {
  return interAgent;
 }


 //
 public void setIntermediateAgent(InterMediateAgent agent) {
  this.interAgent = agent;
 }
 
 //
 public void view() {
  String source = this.interAgent.getData();
  abs.setData(source);
  
  pre.view(abs.getData());
 }
}




Abstraction.java



package pac.bottom;


public class Abstraction {
 //
 private String data;
 
 public String getData() {
  return data;
 }


 public void setData(String data) {
  this.data = data;
 }
 
 //
 public String toString() {
  return data;
 }
}




Presentation.java


package pac.bottom;

public class Presentation {
 String data = null;
 
 public String getData() {
  return data;
 }


 public void setData(String data) {
  this.data = data;
 }



 public void view(Object obj) {
  System.out.println(obj.toString());
 }
}



* reference
– http://en.wikipedia.org/wiki/Presentation-abstraction-control
http://www.devpia.com/net2/EvaCast/Lecture/?cu=view&r=126
http://lakhos.egloos.com/2771689
 

POSA 1 – Layers Pattern

간단하게 말하면 복잡한 시스템을 레이어로 나눠서 Task를 하위 레이어 또는 상위 레이어로의 Delegation을 통해서 구조화를 하는 패턴이라고 생각이 듭니다.

제가 생각하는 내용을 아래의 형태별로 간단하게 코드로 끄적여 봅니다.
아래의 top-down은 layer별 interface가 필요할 것 같고, 그 인터페이스를 layer에 해당하는 기능 클래스(Level0201, Level0202)가 구현을 해서 상위 Layer가 하위 Layer에 Dependency를 줄이면서 사용하면 될 것 같습니다.
그리고, bottom-up은 상속을 통해서 상위 클래스의 메쏘드를 호출하는 형태로 구현을 해 봤습니다. 

혹시 코드보시고, 틀렸다고 생각이 되시는 부분이 있으면 답글로 끄적여 주시면 감사하겠습니다.

1. Top-Down Layer 형태

Level01.java

package layer.down;

import java.nio.ByteBuffer;

public class Level01 {
    ByteBuffer buffer;
    Level02Interface levelTwo; // Level02-1
   
    public void setByteBuffer(ByteBuffer buffer) {
        this.buffer = buffer;
    }
   
    public void setLevel() {
        this.levelTwo = new Level0201();
    }
   

    public void printLevel() {
        if(buffer.getInt() == 4)
            this.levelTwo = new Level0202();
       
        System.out.println(“Level01 printLevel() called”);
        this.levelTwo.foo();       
    }
}


Level02Interface.java

package layer.down;

public interface Level02Interface {

    public void foo();
}


Level0201.java

package layer.down;

public class Level0201 implements Level02Interface {

    @Override
    public void foo() {
        // TODO Auto-generated method stub
        System.out.println(“Level0201 printLevel() called”);
    }
}


Level0202.java

package layer.down;

public class Level0202 implements Level02Interface {

    @Override
    public void foo() {
        // TODO Auto-generated method stub
        System.out.println(“Level0202 printLevel() called”);
    }
}


클라이언트

        ByteBuffer buffer = ByteBuffer.allocate(4);
        buffer.putInt(4);
        buffer.flip();
       
        Level01 layer = new Level01();
        layer.setByteBuffer(buffer);
        layer.setLevel();
        layer.printLevel();   

2. Bottom-Up Layer 형태

SLevel01.java

package layer.up;

public class SLevel01 {
   
    //
    public void read(java.nio.ByteBuffer buffer) {
        System.out.println(“level01 – “+ buffer.getInt());
    }
}

SLevel02.java

package layer.up;

public class SLevel02 extends SLevel01 {

    @Override
    public void read(java.nio.ByteBuffer buffer) {
        System.out.println(“level02 – ” + buffer.getInt());
       
        super.read(buffer);
    }
}

클라이언트

        ByteBuffer buffer = ByteBuffer.allocate(8);
        buffer.putInt(4);
        buffer.putInt(100);
        buffer.flip();
       
        SLevel02 layer = new SLevel02();
        layer.read(buffer);   

POSA 2 – A System of Patterns

디자인 패턴에서 POSA(PATTERN-ORIENTED SOFTWARE ARCHITECTURE) 패턴은 중/고급에 속하는 패턴이라고 일반적으로 인식이 되어 있습니다.
그 중에서 POSA Volume 1은 A System of Patterns 라는 부제로, 디자인 패턴보다는 하이레벨에서 좀더 큰 시스템 개발에서의 패턴을 바라보고 있는거 같습니다.
아래 내용은 http://www.gisdeveloper.co.kr/389 에서 발췌를 하였습니다.

Layer A.P. 어플케이션을 구조화하기 위해 서브 태스크(Subtask)들을 그룹으로 묶기 위해 분해한다. 공통된 추상 레벨에 있는 서브 태스크들끼리 묶어서 그룹으로 분류한다.

Pipes and Filters A.P. 데이터 스트림을 처리하는 시스템 구조를 제공한다. 각 프로세싱 단계는 필터 컴포넌트로 추상화한다. 데이터는 파이프를 통해 연관된 필터들에게 전달된다. 필터들을 다양하게 재조합하여 시스템을 재구축할 수 있다.

Blackboard A.P. 정의되지 않은 도메인에서의 문제를 해결할때 유용하다. 솔루션에 대한 부분적이거나 대략적인 해법을 수립하기 위해 몇가지 특수한 서브시스템들의 지식을 조합한다.

Broker A.P. 분산 소프트웨어 시스템을 구조화할때 유용하다. 분산 소프트웨어 시스템은 분리된 컴포넌트들이 서로 유기적으로 조합되어 운영되는 시스템으로, 이러한 컴포넌트들 간의 통신을 관장하는 역활을 하는 것이 Broker이다.

Model-View-Controller A.P. 모델은 핵심기능과 데이터를 의미하고 뷰는 기능에 의한 데이터의 표현이며 컨트롤은 사용자의 입력에 대한 처리이다. 뷰와 컨트롤러는 사용자의 인터페이스를 구성하며 사용자 인터페이스와 모델간의 일관성 및 정합성을 보장한다.

Presentation-Abstraction-Control A.P. 계층구조를 이루는 에이전트들이 상호작용하는 소프트웨어 시스템에 대한 패턴. 각각의 에이전트는 하나의 어플리케이션의 특정 부분을 전담하며 에이전트는 프리젠테이션/추상/컨트롤로 구성된다.

Microkernel A.P. 변화하는 시스템에 대한 요구사항을 수용할 수 있도록 하는 패턴. 시스템에서 가장 최하단에 위치하는 핵심 기능을 추출해 내며, 추가된 요구사항에 대해 확장기능으로 정의하여 시스템에 손쉽게 추가할 수 있도록 한다.

Reflection A.P. 소프트웨어 시스템의 구조와 동작을 동적으로 변경할 수 있는 메커니즘을 제공.

Whole-Part D.P. 전체(Whole) 객체를 구성하는 컴포넌트(Part)를 정의한다. Whole 객체를 통해 Part 컴포넌트들의 관계를 맺으며, 이 Whole 객체를 통해서만 Part 컴포넌트와 통신할 수 있다.

Master-Slave D.P. 마스터 컴포넌트는 슬레이브 컴포넌트에게 작업을 분산시켜서 최종적으로 슬레이브로부터 그 결과를 취합한다.

Proxy D.P. 실제 컴포넌트가 아닌 대리자를 앞단에 두어 이 대리자를 통해 실제 컴포넌트와 통신을 한다. 실제 컴포넌트의 위치 추상화, 실제 컴포넌트를 사용하기 위한 인증 등과 같은 전처리는 물론 후처리에 대한 기능 추가가 용이하다.

Command Processor D.P. 사용자의 요청을 하나의 객체로 정의하여 관리하며 Undo/Redo와 같은 처리가 가능하다.

View Handler D.P. 시스템의 모든 뷰를 관리하는 책임을 분리하여 뷰들 간의 관계성과 연관된 작업을 쉽게 처리할 수 있도록 한다.

Forwarder-Receiver D.P. 투명한 IPC를 제공하고 Peer를 분리하기 위해 Forwarder와 Receiver를 분리한다.

Client-Dispatcher-Server D.P. 클라이언트와 서버 사이에 디스패처 레이어를 도입한다. 위치 투명성을 제공하고 클라이언트와 서버간의 통신에 대한 세부적인 구현을 캡출화한다.

Publisher-Subscriber D.P. 서로 긴밀하게 관계를 맺고 있는 컴포넌트들 간의 상태에 대해 정합성을 유지하는데 용이하다. Publisher가 책임을 지고 하나의 변경에 대해 다수의 Subscriber에게 변경을 통지한다.