보관물

Archive for the ‘Design patterns’ Category

Decorator pattern

2월 24, 2011 댓글 남기기

Decorator pattern

객체에 추가적인 요건을 동적으로 첨가한다.
데코레이터는 서브클래스를 만드는 것을 통해서 기능을 유연하게 확장할 수 있는 방법을 제공한다.
생성된 ConcreteComponent를 ConcreteDecorator로 감싸는 형식으로 사용된다.
ConcreteDecorator는 또 다른 혹은 같은 ConcreteDecorator로 감싸질 수 있다.

Diagram


Source

Component.java

public abstract class Component {

String varA = “Nothing”;

public String methodA() {

return varA;

}

public abstract String methodB();

}

ConcreteComponent.java

public class ConcreteComponent extends Component {

public ConcreteComponent() {

varA = “ConcreteComponent”;

}

public String methodB() {

return “ConcreteComponent’s methodB()”;

}

}

Decorator.java

public abstract class Decorator extends Component {

public abstract String methodB();

}

ConcreteDecorator.java

public class ConcreteDecorator extends Decorator {

Component component;

public ConcreteDecorator(Component m_Component) {

component = m_Component;

}

public String methodA() {

return component.methodA() + “ConcreteDecorator’s methodA()”;

}

public String methodB() {

return component.methodB() + “ConcreteDecorator’s methodB()”;

}

public String methodC() {

return “Decorator’s new methodC()”;

}

}

Observer pattern

2월 22, 2011 댓글 남기기

Observer pattern

한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고 자동으로 내용이 갱신되는 방식으로 일대다(one-to-many) 의존성을 정의합니다.

Diagram

Source

Subject.java

public interface Subject {

public void registerObserver(Observer o);
public void removeObserver(Observer 0);
public void notifyObservers();

}

ConcreteSubject.java

public class ConcreteSubject implements Subject {

private ArrayList arrObserver;
private SomeData someData;

public ConcreteSubject() {

arrObserver = new ArrayList();
someData = new SomeData( 1 , 2 );

}

public void regsterObserver(Observer o) {

arrObserver.add(o);

}

public void removeObserver(Observer o) {

arrObserver.remove( arrObserver.indexOf(o) );

}

public void notifyObservers() {

for (int i=0 ; i < arrObserver.size() ; i++) {

Observer o = (Observer)arrObserver.get(i);
o.update(someData);

}

}

private void updateData(int arg1, int arg2) {

someData.data1 = arg1;
someData.data2 = arg2;

}

}

Observer.java

public interface Observer {

public void update(SomeData someData);

}

ConcreteObserver.java

public class ConcreteObserver implements Observer {

private Subject concreteSubject;
private SomeData someData;

public ConcreteObserver(Subject m_concreteSubject) {

this.concreteSubject = m_concreteSubject;
this.concreteSubject.registerObject(this);

}

public void update(SomeData m_someData) {

someData = m_someData;

}

}

카테고리:Design patterns 태그:,

Strategy pattern

2월 19, 2011 댓글 남기기

Strategy pattern

알고리즘군을 정의하고 각각을 캡슐화하여 교환해서 사용할 수 있도록 만든다.
strategy를 활용하면 알고리즘을 사용하는 클라이언트와는 독립적으로 알고리즘을 변경할 수 있다.

Diagram

Source

Animal.java

public abstract class Animal {

MoveBehavior moveBehavior;
SoundBehavior soundBehavior;

public Animal() {
}

public abstract void looks();
public void performMove() {

moveBehavior.move();

}

public void performSound() {

soundBehavior.sound();

}
public void setMoveBehavior(MoveBehavior mb) {

moveBehavior = mb;

}
public void setSoundBehavior(SoundBehavior sb) {

soundBehavior = sb;

}

}

Dog.java

public class Dog extends Animal {

public Dog() {

moveBehavior = new MoveWalk();
soundBehavior = new SoundBark();

}
public void looks() {

System.out.println(“It’s a dog”);

}

}

Sparrow.java

public class Sparrow extends Animal {

public Sparrow() {

moveBehavior = new MoveFly();
soundBehavior = new SoundChirp();

}
public void looks() {

System.out.println(“It’s a sparrow”);

}

}

MoveBehavior.java

public interface MoveBehavior {

public void move();

}

MoveWalk.java

public class MoveWalk implements MoveBehavior {

public void move() {

System.out.println(“Walk”);

}

}

MoveFly.java

public class MoveFly implements MoveBehavior {

public void move() {

System.out.println(“Fly”);

}

}

SoundBehavior.java

public interface SoundBehavior {

public void sound();

}

SoundBark.java

public class SoundBark implements SoundBehavior {

public void sound() {

System.out.println(“Bark”);

}

}

SoundChirp.java

public class SoundChirp implements SoundBehavior {

public void sound() {

System.out.println(“Chirp”);

}

}

카테고리:Design patterns 태그:,

[정리중] Software Design 원칙

2월 19, 2011 댓글 남기기

Application에서 달라지는 부분을 찾아내고, 달라지지 않는 부분으로부터 분리시킨다.

달라지는 부분을 찾아서 나머지 코드에 영향을 주지 않도록 “캡슐화”합니다.
그러면 코드를 변경하는 과정에서 의도하지 않은 일이 일어나는 것을 줄이면서 시스템의 유연성은 향상시킬 수 있습니다.

구현이 아닌 인터페이스에 맞춰서 프로그래밍한다.
(상위형식에 맞춰서 프로그래밍한다.)

실제 실행시에 쓰이는 객체가 코드에 의해서 고정되지 않도록, 어떤 상위형식(supertype)에 맞춰서 프로그래밍함으로써 다형성을 활용해야 한다.
변수를 선언할 때는 보통 추상 클래스나 인터페이스 같은 상위 형식으로 선언해야 한다.
객체를 변수에 대입할 때 상위 형식을 구체적으로 구현한 형식이라면 어떤 객체든 집어넣을 수 있기 때문이다. 그렇게 하면 변수를 선언하는 클래스에서 실제 객체의 형식을 몰라도 된다.

상속보다는 구성(composition)을 활용한다.

A class에서 B class를 상속하여 사용하는 방식이 아닌 A class에 B class를 참조하는 레퍼런스 변수를 두어 has a 관계를 가지는 방식으로 구현한다.
구성을 이용하면 유연성이 크게 향상되며 단순히 알고리즘군을 별도의 클래스의 집합으로 캡슐화할 수 있도록 만들어주는 것 뿐 아니라, 구성요소로 사용하는 객체에서 올바른 행동 인터페이스를 구현하기만 하면 실행시에 행동을 바꿀 수도 있게 해 줍니다.

서로 상호작용을 하는 객체 사이에서는 가능하면 느슨하게 결합하는 디자인을 사용해야 한다.

느슨하게 결합하는 디자인을 사용하면 변경 사항이 생겨도 객체 사이의 상호의존성이 최소화되므로 유연한 객체지향 시스템을 구축할수 있다.

OCP(Open-Closed Principle) ; 클래스는 확장에 대해서는 열려 있어야 하지만 코드 변경에 대해서는 닫혀 있어야 한다.

추가,변경된 요구사항을 적용하기 위해 기존 코드의 수정으로 인해 발생될 오류 등을 방지하고 클래스 확장으로 원하는 행동을 자유롭게 추가하는 것으로 유연한 환경을 제공한다.

참고자료

Head First : Design Patterns 스토리가 있는 패턴 학습법

<<To be continued>>