'Pattern'에 해당되는 글 16건

  1. 2011.01.09 flyweight pattern by 파이팅야 3
  2. 2011.01.02 decorator pattern by 파이팅야 4
  3. 2010.11.28 factory method pattern by 파이팅야 2
  4. 2010.11.21 builder pattern by 파이팅야 2
  5. 2010.06.29 observer pattern by 파이팅야 2
  6. 2008.08.19 iterator pattern by 파이팅야 1
  7. 2008.08.08 chain of responsibility by 파이팅야 3
  8. 2008.04.25 template method pattern by 파이팅야 2
  9. 2008.04.25 strategy pattern by 파이팅야 1
  10. 2008.04.25 state pattern by 파이팅야 1

flyweight pattern

Pattern 2011. 1. 9. 16:52
  • 개요
    • 공유 가능한 정보를 객체 형태로 정의하고 재활용(Object Pooling) 해서 객체(컴퓨터 자원)수를 최소함으로 가볍게 합니다. (예로, 비행기 게임에서 적들의 비행기에 사용하는 이미지가 있을 때 유사한 많은 적 객체들마다 이미지를 가지고 있으면 많은 이미지들을 사용하게 되므로 자원을 많이 사용하게 된다. 그러나 해당 적 이미지들을 공유하는 객체를 사용함으로 자원을 가볍게 사용하도록 할 수 있다.)
  • 구조 예
    • Marine과 Firebat 은 Client에게 공유(재활용)할려는 객체이고, UniqueHero는 공유하지 않는 객체이다. Barrack 으로 Factory Method Pattern 이 적용 되어 있다. (Marine과 Firebat은 생성된 객체를 재 사용하지만, UniqueHero는 매번 객체를 생성한다. Client에서는 Marine과 UniqueHero를 같은 인터페이스로 접근할 수 있다.)

 

  • 소스

public abstract class AUnit {
 abstract void attack();
}
public class Marine extends AUnit {
 void attack() {
  System.out.println("marine attack()");
 }
}
public class Firebat extends AUnit {
 void attack() {
  System.out.println("firebat attack()");
 }
}
public class UniqueHero extends AUnit {
 void attack() {
  System.out.println("uniqueHero attack()");
 }
}
public class Barrack {
 private HashMap<Integer, AUnit> unitMap = new HashMap<Integer, AUnit>();

 public AUnit getUnit(int unitType) {
  if (unitType == 3)
   return new UniqueHero();
 
  if (unitMap.get(unitType) != null)
   return unitMap.get(unitType);
 
  AUnit unit = null;
  if (unitType == 1)
    unit = new Marine();
  else if (unitType == 2)
    unit = new Firebat();
  else
    return null;
 
  unitMap.put(unitType, unit);
  return unit;
 }
 public int getUnitSize() {
  return unitMap.size();
 }
}
public class Client {
 public static void main(String[] args) {
  Barrack barrack = new Barrack();
  AUnit marine = barrack.getUnit(1); // marine 생성 (+1)
  marine.attack();

  AUnit marine2 = barrack.getUnit(1); // 이미 생성된 marine 재 사용
  marine2.attack();

  AUnit firebat = barrack.getUnit(2); // firbat 생성 (+1)
  firebat.attack();
  
  AUnit uniqueHero = barrack.getUnit(3); // 매번 새로운 uniqueHero 생성
  uniqueHero.attack();
  
  System.out.println("hashMap size[" + barrack.getUnitSize() + "]");
 }
}

결과 화면
marine attack()
marine attack()
firebat attack()
uniqueHero attack()
unit size[2]


Posted by 파이팅야
,

decorator pattern

Pattern 2011. 1. 2. 20:47
  • 개요
    • the decorator pattern is a design pattern that allows new/additional behaviour to be added to an existing object dynamically. (아래의 '구조 예'에서 새로운 추가 행동은 Sugar.getIngredient()안의 ", Sugar" 이다. 여기서는 문자열을 추가로 반환 하지만, 구현에 따라서 기능이나 비즈니스를 추가로 호출해도 된다.)
    • 주어진 상황 및 용도에 따라 어떤 객체에 책임을 덧붙이는 패턴으로, 기능 확장이 필요할 때 서브클래싱 대신 쓸 수 있는 유연한 대안이 될 수 있다. (클래스의 상속을 사용하면 클래스 설계시에 해당 클래스의 기능이 정적으로 정해져서 동적으로 기능을 추가할 수가 없다. 아래의 예에서는 BlackCoffee및 MilkCoffee 클래스에 동적으로 Sugar와 Cream을 추가할 수 있다. Sugar를 여러 번 BlackCoffee에 추가할 수도 있다.)
  • 구조 예



  • 소스
public interface ICoffee {
public String getIngredient();
public void description();
}
public class BlackCoffee implements ICoffee {
public void description() {
System.out.println("black coffee");

}
public String getIngredient() {
return "coffee";
}
}
public class MilkCoffee implements ICoffee {
public void description() {
System.out.println("milk coffee");
}
public String getIngredient() {
return "coffee" + ", milk";
}
}
public abstract class ACoffeeDecorator implements ICoffee {
protected ICoffee coffee = null;
public ACoffeeDecorator(ICoffee coffee)
{
this.coffee = coffee;
}
public void description() {
}
abstract public String getIngredient();
}
public class Sugar extends ACoffeeDecorator {
public Sugar(ICoffee coffee) {
super(coffee);
}
public String getIngredient() {
return super.coffee.getIngredient() + ", Sugar";
}
}
public class Cream extends ACoffeeDecorator {
public Cream(ICoffee coffee) {
super(coffee);
}
public String getIngredient() {
return super.coffee.getIngredient() + ", Cream";
}
}
public class Client {
public static void main(String[] args) {
System.out.println("--- black coffee ---");
ICoffee blackCoffee = new BlackCoffee();
blackCoffee = new Sugar(blackCoffee);
System.out.println(blackCoffee.getIngredient());

blackCoffee = new Sugar(blackCoffee);
System.out.println(blackCoffee.getIngredient());

blackCoffee = new Cream(blackCoffee);
System.out.println(blackCoffee.getIngredient());

System.out.println("--- milk coffee ---");
ICoffee milkCoffee = new Cream(new MilkCoffee());
System.out.println(milkCoffee.getIngredient());
}
}

결과 화면 :
--- black coffee ---
coffee, Sugar
coffee, Sugar, Sugar
coffee, Sugar, Sugar, Cream
--- milk coffee ---
coffee, milk, Cream
  • 구현 관련
    • Decorate 되는 클래스(BlackCoffee, MilkCoffee) 와 Decorate 하는 클래스(Sugar, Cream)가 구분 되어야 한다.
    • 최상위 클래스 or 인터페이스(ICoffee) 에서는 데이터 멤버가 없거나 최소화 하고, interface 갯수도 최소화하는 것이 좋다. 객체에 기능을 추가 할려면 많은 객체들이 사용되는데 최상위 클래스에서 데이터 멤버가 많으면 여러 객체들에서 메모리를 많이 차지하게 되고, 인터페이스가 많으면 불필요한 인터페이스에 대해 재정의 해야 한다.
    • ACoffeeDecorator 클래스 없이 ICoffe를 바로 구현하는 Sugar와 Cream을 두는 구조로 만들면, ICoffee에서는 'Decorator역할을 하는 Sugar, Cream등의 인터페이스'와 'Decorator의 대상이 되는 BlackCoffee, MilkCoffee 등의 인터페이스'를 같이 정의하므로 두가지 중 한가지 종류의 인터페이스및 멤버를 추가 하거나 확장하기에 좋지 않다. 두가지 역할을 하므로 SRP에도 어긋난다.
    • Decorator 클래스(ACoffeeDecorator)는 객체생성을 못하게 abstract class로 만들는것이 좋다.
    • ICoffee와 ACoffeeDecorator에 cost()를 두고 ICoffee와 ACoffeeDecorator를 구현하는 클래스들에서 cost()를 클래스별 가격을 반환하게 구현하면 BlackCoffee 가격에 2번 Sugar를 추가한 가격을 합산할 수 있다.
  • 차이점
    • Decorator 패턴은 객체에게 추가 기능을 위해 객체로 감싸주는 역할을 하며, Strategy 패턴은 내부 비즈니스(알고리즘)을 위임 시키기 위한 것이다.
  • 참고
    • java.io class도 데코레이터 패턴이다. InputStream in = new BufferedInputStream(new FileInputStream());

Posted by 파이팅야
,

factory method pattern

Pattern 2010. 11. 28. 19:33
  • 개요
    • 객체를 생성하기 위해 인터페이스를 정의하지만, 어떤 클래스의 인스턴스를 생성할지에 대한 결정은 서브클래스에서 책임지도록 한다.
  • 구조 예


  • 소스
public class Unit {
protected void move() {
System.out.println("Unit move");
}
protected void attack() {
System.out.println("Unit attack");
}
}
public class Marine extends Unit {
protected void attack() {
System.out.println("Marine move");
}
protected void move() {
System.out.println("Marine attack");
}
}
public class Battlecruiser extends Unit {
protected void attack() {
System.out.println("Battlecruiser move");
}
protected void move() {
System.out.println("Battlecruiser attack");
}
}
public abstract class Factory {
abstract Unit createUnit();
public void operation() {
Unit unit = createUnit();
unit.move();
unit.attack();
}
}
public class Barrack extends Factory {
Unit createUnit() {
return new Marine();
}
}
public class StarPort extends Factory {
Unit createUnit() {
return new Battlecruiser();
}
}
public class Client {
public static void main(String[] args) {
Factory barrack = new Barrack();
barrack.operation();
Factory starPort = new StarPort();
starPort.operation();
}
}



Posted by 파이팅야
,

builder pattern

Pattern 2010. 11. 21. 16:35
  • 개요 : 객체를 생성하되 그 객체를 구성하는 부분 부분을 먼저 생성(아래에서는 buildHead, buildBody, buildFoot)하고, 이를 조합함으로서 전체 객체를 생성하는 패턴
  • 구조 예

  • 소스
public abstract class ACharacterBuilder {
protected Character character = null;
abstract void buildHead();
abstract void buildBody();
abstract void buildFoot();
public void createNewCharacter() {
this.character = new Character();
}
public Character getResultCharacter() {
return this.character;
}
}
public class HumanBuilder extends ACharacterBuilder {
void buildBody() {
this.character.setBody("인간몸 생성");
}
void buildFoot() {
this.character.setFoot("인간발 생성");
}
void buildHead() {
this.character.setHead("인간머리 생성");
}
}
public class MonsterBuilder extends ACharacterBuilder {
void buildBody() {
this.character.setBody("괴물몸 생성");
}
void buildFoot() {
this.character.setFoot("괴물발  생성");
}

void buildHead() {
this.character.setHead("괴물머리 생성");
}
}
public class Character {
private String head = "";
private String body = "";
private String foot = "";
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getFoot() {
return foot;
}
public void setFoot(String foot) {
this.foot = foot;
}
public String getHead() {
return head;
}
public void setHead(String head) {
this.head = head;
}
public void show() {
System.out.println(getHead());
System.out.println(getBody());
System.out.println(getFoot());
}
}
public class Director {
public void construct(ACharacterBuilder chracterBuilder) {
chracterBuilder.createNewCharacter();
chracterBuilder.buildHead();
chracterBuilder.buildBody();
chracterBuilder.buildFoot();
}
}
public class Client {
public static void main(String[] args) {
ACharacterBuilder humanBuilder = new HumanBuilder();
ACharacterBuilder monsterBuilder = new MonsterBuilder();
Director director = new Director();
// 인간생성
System.out.println("===== 인간생성 시작 =====");
director.construct(humanBuilder);
Character humanA = humanBuilder.getResultCharacter();
humanA.show();
System.out.println("===== 괴물생성 시작 =====");
director.construct(monsterBuilder);
Character monsterA = monsterBuilder.getResultCharacter();
monsterA.show();
}
}
  • 구현관리
    • Character(Product)의 속성이 변경되면 ACharacterBuilder와 구현클래스들의 변경이 있게 되므로 Character(Product)의 속성에 대한 설계를 명확히 하는것이 중요하다. Character(Product)를 인덱서 형식으로 만들면 Character(Product) 클래스의 변경은 없을것 같다. (위의 예에서는 Character 에 map<string, string>을 가지고 있고 map을 추가하고 조회하는 메소드를 만들면 추후 Charater에 멤버를 추가 및 삭제할 때 Character class의 소스를 수정할 일이 없다.)
    • Character(Product)가 여러개일 경우에는 ICharacter와 같이 추상화해서 사용해도 괜찮을것 같다.
  • 참고

Posted by 파이팅야
,

observer pattern

Pattern 2010. 6. 29. 00:12
정의 : 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고 자동으로 내용이 갱신되는 방식으로 일대다 의존성을 정의합니다.


Publisher publisher = new publisher();
new SubscriberA(publisher);
new SubscriberB(publisher);
publisher.setBook("aaa");
publisher.setBook("bbb");

// push 방식
Publisher에서 Subscriber들에게 Publish할 때 IObserver.update(전달값) 호출함

// pull 방식
Publisher에서 Subscriber들에게 Publish할 때 IObserver.update(Publisher) 호출하고 Subscriber에서 Publisher의 변경된 book값을 조회함
Posted by 파이팅야
,

iterator pattern

Pattern 2008. 8. 19. 20:46

. 정의

복합 객체 요소들(aggregate)의 내부 표현 방식을 공개하지 않고도 순차적으로 접근할 수 있는 방법을 제공한다.

 

사용자 삽입 이미지

 

public class Client {

public static void main(String[] args) {

         ArrayListAggregate newList = new ArrayListAggregate();

         newList.add('a');

         newList.add('c');

         newList.add('b');

         newList.add('d');

         IIterator iterator = newList.createIterator();

 

         Object obj = null;

         while(iterator.hasNext()) {

                  obj = iterator.next();

                  System.out.println(obj);

         }

        

         LinkedListAggregate newList2 = new LinkedListAggregate();

         newList2.add(1);

         newList2.add(3);

         newList2.add(2);

         newList2.add(4);

        

         IIterator iterator2 = newList2.createIterator();

 

         while(iterator2.hasNext()) {

                  obj = iterator2.next();

                  System.out.println(obj);

         }

--------------------------------------------------------------------

public interface IAggregate {

         public IIterator createIterator();

--------------------------------------------------------------------

public class ArrayListAggregate implements IAggregate {

         ArrayList arrayList = new ArrayList();

         public IIterator createIterator() {

                  return new ArrayListIterator(this);

         }

         public int size() {

                  return this.arrayList.size();

         }

         public boolean add(Object obj) {

                  return this.arrayList.add(obj);

         }

         public Object get(int index) {

                  return this.arrayList.get(index);

         }

--------------------------------------------------------------------

public class LinkedListAggregate implements IAggregate {

         LinkedList linkedList = new LinkedList();

         public IIterator createIterator() {

                  return new LinkedListIterator(this);

         }

         public int size() {

                  return this.linkedList.size();

         }

         public boolean add(Object obj) {

                  return this.linkedList.add(obj);

         }

         public Object get(int index) {

                  return this.linkedList.get(index);

         }

--------------------------------------------------------------------

public interface IIterator {

         abstract boolean hasNext();

         abstract Object next();

--------------------------------------------------------------------

public class ArrayListIterator implements IIterator {

         ArrayListAggregate aggregate = null;

         int currentIndex = -1;

        

         public ArrayListIterator(ArrayListAggregate arrayListAggregate) {

                  this.aggregate = arrayListAggregate;

         }

         public Object next() {

                  return this.aggregate.get(this.currentIndex);

         }

         public boolean hasNext() {

                  this.currentIndex++;

                  if (this.currentIndex >= this.aggregate.size() ||

                           this.aggregate.get(this.currentIndex) == null)

                           return false;

                  else

                           return true;

         }

--------------------------------------------------------------------

public class LinkedListIterator implements IIterator {

         LinkedListAggregate aggregate = null;

         int currentIndex = -1;

 

         public LinkedListIterator(LinkedListAggregate linkedListAggregate) {

                  this.aggregate = linkedListAggregate;

         }

         public Object next() {

                  return this.aggregate.get(this.currentIndex);

         }

         public boolean hasNext() {

                  this.currentIndex++;

                  if (this.currentIndex >= this.aggregate.size()

                     || this.aggregate.get(this.currentIndex) == null)

                           return false;

                  else

                           return true;

         }

Posted by 파이팅야
,

chain of responsibility

Pattern 2008. 8. 8. 18:41

. 의도

메시지를 보내는 객체와 이를 받아 처리하는 객체들 간의 결합도를 없애기 위한 패턴입니다. 하나의 요청에 대한 처리가 반드시 한 객체에서만 되지 않고, 여러 객체에게 그 처리 기회를 주려는 것입니다.

 

. 예제

logLevel의 값에 따라서 처리가능하면 로그를 쌓고 아니면 다른 객체에게 처리하라고 책임을 넘김

사용자 삽입 이미지

public class Client {

         public static void main(String[] args) {

                  ALog info = new Info();

                  ALog warning = new Warning();

                  ALog debug  = new Debug();

                 

                  // 체인 형성

                  info.setLog(warning);

                  warning.setLog(debug);

                 

                  info.writeLog(-100);

                  info.writeLog(1);

                  info.writeLog(2);

                  info.writeLog(3);

                  info.writeLog(100);

----------------------------------------------------------------

public abstract class ALog {

         public ALog log = null;

         public void setLog(ALog log) {

                  this.log = log;

         }

         abstract void writeLog(int logLevel);

----------------------------------------------------------------

public class Info extends ALog {

         void writeLog(int logLevel) {

                  if(logLevel <= 1) {

                           System.out.println("info log");

                  } else {

                           if (super.log != null)

                                   super.log.writeLog(logLevel);

                  }

         }

----------------------------------------------------------------

public class Warning extends ALog {

         void writeLog(int logLevel) {

                  if(logLevel == 2) {

                           System.out.println("warning log");

                  } else {

                           if (super.log != null)

                                   super.log.writeLog(logLevel);

                  }

         }

----------------------------------------------------------------

public class Debug extends ALog {

         void writeLog(int logLevel) {

                  if (logLevel >= 3) {

                           System.out.println("debug log");

                  } else {

                           if (super.log != null)

                                   super.log.writeLog(logLevel);

                  }

         }

Posted by 파이팅야
,

template method pattern

Pattern 2008. 4. 25. 21:03

template method pattern에서는 메소드에서 알고리즘의 골격을 정의합니다. 알고리즘의 여러 단계 중 일부는 서브클래스에서 구현할 수 있습니다. 템플릿 메소드를 이용하면 알고리즘의 구조는 그대로 유지하면서 서브클래스에서 특정 단계를 재정의할 수 있습니다.

상위 클래스에서 처리의 흐름을 정하고 하위 클래스에서 구체적인 내용을 결정하는 디자인 패턴입니다.

예제)

사용자 삽입 이미지

public abstract class AWorker {

             protected final void work() {

                           attendance();

                           doIt();

                           leave();

             }

             private void attendance() {

                           System.out.println("출근하다.");

             }

             private void leave() {

                           System.out.println("퇴근하다.");

             }

             abstract void doIt();

--------------------------------------------------------------

public class Designer extends AWorker {

             void doIt() {

                           System.out.println("디자인 작업함");

             }

--------------------------------------------------------------

public class Programmer extends AWorker {

             void doIt() {

                           System.out.println("프로그램 작업함");

             }

--------------------------------------------------------------

public class Client {

             public static void main(String[] args) {

                           AWorker worker = null;

                           worker = new Designer();

                           worker.work();

                          

                           worker = new Programmer();

                           worker.work();

             }

--------------------------------------------------------------

출근하다.

디자인 작업함

퇴근하다.

출근하다.

프로그램 작업함

퇴근하다.

Posted by 파이팅야
,

strategy pattern

Pattern 2008. 4. 25. 18:39

Strategy Pattern알고리즘 군을 정의하고 각각을 캡슐화하여 교환해서 사용할 수 있도록 만든다. 바뀌는 부분을 인터페이스로 분리하여 처리하고, 그 인터페이스의 구현체를 바꿈으로서 로직을 변경한다.

(if or switch문으로 분기되는 부분이 있을 때는 strategy pattern을 고려해 보고, 분기되고 속성의 변화에 의해 행동이 바뀌면 state pattern을 고려해 보면 될 것 같다. 동적으로 type code성인 iGame값이 바뀌어야 할때 이 패턴을 사용해야 겠다. 동적으로 바뀌지 않고 불변이면 상속구조도 괜찮다.)


예제) StarcraftMine게임 하는 부분

사용자 삽입 이미지

public interface IGame {

             void play();

------------------------------------------------------

public class Starcraft implements IGame {

             public void play() {

                           System.out.println("starcraft 게임중...");

             }

------------------------------------------------------

public class Mine implements IGame {

             public void play() {

                           System.out.println("지뢰찾기 게임중");

             }

------------------------------------------------------

public class PCGame {

             private IGame iGame;

             public PCGame(IGame iGame) {

                           this.iGame = iGame;

             }

             public void play() {

                           iGame.play();

             }

             public IGame getIGame() {

                           return iGame;

             }

             public void setIGame(IGame game) {

                           iGame = game;

             }

------------------------------------------------------

public class Client {

             public static void main(String[] args) {

                           PCGame pcGame = new PCGame(new Starcraft());

                           pcGame.play();    // starcraft 게임중...

                          

                           pcGame.setIGame(new Mine());

                           pcGame.play();    // 지뢰찾기 게임중

             }

Posted by 파이팅야
,

state pattern

Pattern 2008. 4. 25. 09:58

State Pattern을 이용하면 객체의 내부 상태가 바뀜에 따라서 객체의 행동을 바꿀 수 있습니다. 마치 객체의 클래스가 바뀌는 것과 같은 결과를 얻을 수 있습니다.

(Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.)

 

State 패턴은 상태(state)를 클래스로 표현한다. 현실세계에서 상태를 사물(object)로 보는 일은 거의 없기 때문에, 상태를 클래스로 표현하는 일은 어색할 수 있다. 그러나, 상태를 클래스로 표현하면 클래스의 교체를 통해서상태의 변화를 나타낼 수 있고, 새로운 상태를 추가해야 하는 경우에는 무엇을 프로그램 하면 되는지 명확해진다.

예제) '마이너스계좌'(MinusAccount)를 사용하는 사용자의 잔금(balance)의 변화에 따라서 계좌의 상태값이 변화한다. Low는 -금액이 되었을때 상태이며 더이상 출금이 안됨, Middle는 0~99사이의 금액일때 상태, High는 100이상의 금액일때 상태이다.

사용자 삽입 이미지

public abstract class AState {

             private double balance;

             private MinusAccount minusAccount;

             public AState(MinusAccount minusAccount) {

                           this.minusAccount = minusAccount;

             }

             protected abstract void deposit(double balance);

             protected abstract void withdraw(double balance);

             Getter/ Setter …

--------------------------------------------------------------------

public class Low extends AState {

             public Low(MinusAccount minusAccount) {

                           super(minusAccount);

             }

             protected void deposit(double balance) {

                           setBalance(getBalance() + balance);

                           if (getBalance() >= 0)

                                        getMinusAccount().setState(
                                            getMinusAccount().getMiddle(), getBalance());

             }

             protected void withdraw(double balance) {

                           System.out.print("*출금불가*,");

             }

--------------------------------------------------------------------

public class Middle extends AState {

             public Middle(MinusAccount minusAccount) {

                           super(minusAccount);

             }

             protected void deposit(double balance) {

                           setBalance(getBalance() + balance);

                           if (getBalance() >= 99)

                                        getMinusAccount().setState(
                                           getMinusAccount().getHigh(), getBalance());

             }

             protected void withdraw(double balance) {

                           setBalance(getBalance() - balance);

                           if (getBalance() < 0)

                                        getMinusAccount().setState(
                                            getMinusAccount().getLow(), getBalance());

             }

--------------------------------------------------------------------

public class High extends AState {

             public High(MinusAccount minusAccount) {

                           super(minusAccount);

             }

             protected void deposit(double balance) {

                           setBalance(getBalance() + balance);

             }

             protected void withdraw(double balance) {

                           setBalance(getBalance() - balance);

                           if (getBalance() < 100)

                                        getMinusAccount().setState(
                                            getMinusAccount().getMiddle(), getBalance());

             }

--------------------------------------------------------------------

public class MinusAccount {

             private Low low;

             private Middle middle;

             private High high;

             private AState state;

            

             public MinusAccount() {

                           low         = new Low(this);

                           middle    = new Middle(this);

                           high       = new High(this);

                           state = middle;

             }

             public void deposit(double balance) {

                           System.out.print("[" + state.getClass().getName() + "],");

                           state.deposit(balance);

                           System.out.println("[" + state.getClass().getName() + "], +"

                                                + balance + ", balance[" + state.getBalance() + "]");

             }

             public void withdraw(double balance) {

                           System.out.print("[" + state.getClass().getName() + "],");

                           state.withdraw(balance);

                           System.out.println("[" + state.getClass().getName() + "], -"

                                                + balance + ", balance[" + state.getBalance() + "]");

             }

Getter/ Setter …

--------------------------------------------------------------------

public class Client {

             public static void main(String[] args) {

                           MinusAccount minusAccount = new MinusAccount();

                           minusAccount.deposit(10); 
                                  // [Middle],[Middle], +10.0, balance[10.0]

                           minusAccount.withdraw(30);             
                                  // [Middle],[Low], -30.0, balance[-20.0]

                           minusAccount.withdraw(5); 
                                  // [Low],*출금불가*,[Low], -5.0, balance[-20.0]

                           minusAccount.deposit(100);             
                                  // [Low],[Middle], +100.0, balance[80.0]

                           minusAccount.deposit(150);             
                                  // [Middle],[High], +150.0, balance[230.0]



구현관련

   - MinusAccount에서 state값을 map으로 들고 있고 map의 key값인 string으로 조회하면 매번 new해서 객체를 생성하지 않아도 될 듯... 아래의 '다른 예' 참고


다른 예




 


Posted by 파이팅야
,