E D R , A S I H C RSS

Programming With Interface

œ˜: Holub on Patterns by Allen Holub

ฑ…—„œ๋Š” ๋ง•œ‹ค. ๋งŽ€ œ๋ฐœž๋“ค„Ž˜Šค ๋ณด๋‹ค๋Š” ƒ†„ ‚ฌšฉ•˜—ฌ œ๋ฐœ•œ‹ ... ธ๋ ‡๋‹ค! ‚ฌ‹ด๋‹ค. ๋‚˜๋„ —ฌง€ป „Ž˜Šค๋กœ ๋ฌดžฅ•œ ฝ”๋“œ๋ฅผ ๋ณดง€ ๋ชป–ˆ๋‹ค.
–ธ œ๋‚˜ œ๋ฐœ„ • •Œ '–ด๋ผ~ ฐ™€ •˜๋Š”๋ฐ? ฑฐ Base ด๋ž˜Šค ๋งŒ๋“ค–ด„œ œ„๋กœ ˜ฌ๋ • ๋Š”๋ฐ?' ผ๋ง˜ ‹ˆ๋„ ฃผง€ •Š  ‹–‰•œ‹ค. ๋‹˜•„„ ‚ฌšฉ•˜๋Š” ฝ”๋“œ๋ฅผ ƒ„•œ‹ค. '™€šฐ~! •œฒฐ น”๋”•กŒ๋Š”ฑธ?' •˜ง€๋งŒ ˜‚ฐ—ˆ๋‹ค. ‹œ„ง€๋‚˜„œ ๋จผฐ€ ถ”ฐ€•  ๋™ž‘๋“คƒฒผ๋‹ค.  œ  ˜ธฐ ‹œž‘•œ‹ค. Base ด๋ž˜Šค ๋ถ€„ฐ...  ˜  ๋‚˜‹ˆ ปดŒŒด ๋˜ง€ •Š๋Š”๋‹ค. ฝ”๋“œ ˆ˜ •˜ —ฌŒŒฐ€ •˜œ„ ด๋ž˜Šค๋“ค—ฒŒ นŒง€ ๋ฏธœ‹ค.  •๋ง ๋ฏธœ‹ค. ด๋Ÿฐ ƒ†„ †ต•œ „ธต ตฌกฐ๋Š” ƒœ„ ด๋ž˜Šค™€ •˜œ„ ด๋ž˜Šค˜ ฒฐ•ฉ๋„๋ฅผ ๋†’—ฌค€๋‹ค. ง€๋‚˜ ˜ฒŒ ฌฒŒ..! ๋™ฐ•˜ง€ •Š๋Š”ฐ€? •˜๋‚˜๋ฅผ  ณค๋Š”๋ฐ ˆ˜ ••  บผ๋ฆฌฐ€ ๋งˆตฌ Ÿ•„ง€๋Š” ƒ™ฉ„...
ƒ†„ ‚ฌšฉ•˜๋Š” ƒ™ฉ„ ตญ•œ ‹œœ••  ฒƒฐ™๋‹ค. ƒœ„ ด๋ž˜Šค˜ ธฐ๋Šฅ„ 100%๋กœ ‚ฌšฉ•˜๋ฉด„œ ถ”ฐ€ ธฐ๋Šฅ„ •„š”๋กœ •˜๋Š” ฒดฐ€ •„𔕠•Œ! .. ด๋Ÿฐ ƒ™ฉผ ๋•Œ๋Š” ƒ†„ ‚ฌšฉ•ด๋„ ›„’ด ๋‘๋ ง€ •Š„ ฒƒ ฐ™๋‹ค. GoF˜ ฑ…ด๋‚˜‹ค๋ฅธ DP˜ ฑ…๋“ค€ •ƒ ๋ง•œ‹ค. ƒ† ๋ณด๋‹ค๋Š” „Ž˜Šค๋ฅผ †ต•ด ๋‹˜•„„ ‚ฌšฉ•˜ ... œ ๋ฅผ  œ••Œ ฒƒฐ™๋‹ค. ๋™ฐ•˜ง€ •Š๋Š”ฐ€? Base ด๋ž˜Šค๋ฅผ ˆ˜ •• •Œ๋งˆ๋‹•˜œ„ ด๋ž˜Šค๋ฅผ ˆ˜ ••••˜๋Š” ƒ™ฉด ๋ฐœƒ•œ‹ค๋ฉด ฑด „Ž˜Šค๋ฅผ †ต•ด ๋‹˜•„„ ง€›•˜๋Š”ฒŒ ๋” ๋‚ซ๋‹ค๋Š” ‹ ˜ด๋‹ค. ฒด๋Š” –ธ œ๋‚˜ SRP (Single Responsiblity Principle)„ ง€œ••œ‹  ƒฐ•œ‹ค.

Holub‚ฌšฉ•˜๋Š” ˜ˆ œ๋ฅผ ๋ณดž. ƒ†„ ‚ฌšฉ•Stack„ ตฌ˜„•œ‹ค.
class Stack extends ArrayList {

 private int topOfStack = 0;

 

 public void push(Object article) {

  add(topOfStack++, article);

 }

 

 public Object pop() {

  return remove(--topOfStack);

 }

 

 public void pushMany(Object[] articles) {

  for(int i=0; i<articles.length; ++i) 

   push(articles[i]);

 }

}

™„๋ฒฝ•œ Stackด๋‹ค. •˜ง€๋งŒ ๋‹Œ ฝ”๋“œ๋ฅผ ‚ฌšฉ•˜๋ฉด šฐ๋ฆฌ๋Š” Stack ฒดฐ€ –ด๋–ปฒŒ ๋Œ•„ฐˆง€ ˜ˆธก •  ˆ˜ —†๋‹ค.

Stack aStack = new Stack();

stack.push("1");

stack.push("2");

stack.clear(); // ??? ArrayList˜ ๋ฉ”†Œ๋“œด๋‹ค...;;
ž ๋ชจ๋“  ฐ’„ clear ๋ฅผ ‚ฌšฉ•‚ญ œ–ˆ๋Š”๋ฐ topOfStack˜ ฐ’€ —ฌ „žˆ 3ฒƒด๋‹ค. ž ƒ†„ †ต•œ ๋ฌธ œ๋ฅผ •˜๋‚˜ •ŒฒŒ ๋˜—ˆ๋‹ค. ƒ†„ ‚ฌšฉ•˜๋ฉด ›˜ •Š๋Š” ƒœ„ ด๋ž˜Šค˜ ๋ฉ”†Œ๋“œนŒง€ ƒ†•  ˆ˜ žˆ๋‹ค ๋Š” ฒƒด๋‹ค.

ƒœ„ ด๋ž˜Šคฐ€ ฐ€ง€๋Š” ๋ฉ”†Œ๋“œฐ€  ๋‹ค๋ฉด ๋ชจ๋‘ ˜๋ฒ„ด๋”ฉ•˜๋Š” ๋ฐฉ๋ฒ•žˆง€๋งŒ ๋งŒ•€ฐฎ„  •๋„๋กœ ๋งŽ€ ๋ฉ”†Œ๋“œฐ€ žˆ๋‹ค๋ฉด ˜ค๋žœ ‹œ„ฑธ๋ฆด ฒƒด๋‹ค. ธ๋ฆฌ  ๋งŒ•ƒœ„ ด๋ž˜Šคฐ€ ˆ˜ •๋œ‹ค๋ฉด ๋‹‹œ —ฌŒŒฐ€ •˜œ„ ด๋ž˜Šค—ฒŒ  „‹ฌ๋œ‹ค. ๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•œผ๋กœ •ˆ˜๋ฅผ ˜ค๋ฒ„ด๋”ฉ•˜—ฌ ˜ˆ™ธ๋ฅผ ๋˜ง€๋„๋ก ๋งŒ๋“ค–ด ›˜•Š๋Š” ˜œ„ ๋ง‰„ ˆ˜ žˆง€๋‹ค. •˜ง€๋งŒ ด๋Š” ปดŒŒƒ€ž„ —๋Ÿฌ๋ฅผ ๋Ÿฐƒ€ž„ —๋Ÿฌ๋กœ ๋ฐ”พธ๋Š” ฒƒด๋‹ค. ธ๋ฆฌ  LSP (Liskov Sustitution Principle : "ธฐ๋ฐ˜ ด๋ž˜Šค๋Š” ŒŒƒด๋ž˜Šค๋กœ ๋Œ€ฒด ฐ€๋Šฅ•••œ‹ค") ›น™„ –ดธฐฒŒ ๋œ‹ค. ๋‹—ฐžˆ ArrayList๋ฅผ ƒ†๋ฐ›€ Stack€ clear ๋ฉ”†Œ๋“œ๋ฅผ ‚ฌšฉ•  ˆ˜ žˆ–ด••œ‹ค. ธ๋Ÿฐ๋ฐ ˜ˆ™ธ๋ฅผ ๋˜ง€๋‹ค๋‹ˆ ๋งด ๋˜๋Š”ฐ€?

Stack„ ตฌ˜„•˜๋Š” ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•€ ƒ† ๋Œ€‹  บกА™”๋ฅผ ‚ฌšฉ•˜๋Š” ฒƒด๋‹ค.
class Stack {

 private int topOfStack = 0;

 private ArrayList theData = new ArrayList();

 

 public void push(Object article){

  theData.add(topOfStack++, article);

 }

 

 public Object pop() {

  return theData.remove(--topOfStack);

 }

 

 public void pushMany(Object [] articles) {

  for(int i=0; i<articles.length; ++i)

   push(articles[i]);

 }

 

 public int size() {

  return return theData.size();

 }

}
ž.. Stackณผ ArrayList„˜ ฒฐ•ฉ๋„ฐ€ ๋งŽด ๋‚ฎ•„ กŒ๋‹ค. ตฌ˜„•˜ง€ •Š€ clear ๋”ฐœ„ ˜œ ๋˜ง€๋„ •Š๋Š”๋‹ค. ™ ง€ •„„ ‚ฌšฉ•˜๋Š” ๋ฐฉ๋ฒ•ด ๋” ๋‚˜€ ฒƒ ฐ™๋‹ค. ด๋Ÿฐ ๋ง๋„ žˆ๋‹ค. ƒ† ๋ณด๋‹ค๋Š” •„„ ‚ฌšฉ•˜ ... ž ๋‹‹œ ๋ณธ๋ก œผ๋กœ ๋“ค–ด™€  € Stack„ ƒ†•˜๋Š” ด๋ž˜Šค๋ฅผ ๋งŒ๋“ค–ด ๋ณดž. MonitorableStack€ Stack˜ œ†Œ, œ๋Œ€ ฌธฐ๋ฅผ ธฐ–ต•˜๋Š” Stackด๋‹ค.
class MonitorableStack extends Stack {

 private int maxHeight = 0;

 private int minHeight = 0;

 

 public void push(Object o) { 

  push(0);

  if(size() > maxHeight)

   maxHeight = size();

 }

 

 public Object pop() {

  Object poppedItem = pop();

  if(size() < minHeight)

   minHeight = size();

  return poppedItem;

 }

 

 public int maximumSize() { return maxHeight; }

 public int minimumSize() { return minHeight; }

}
น”๋”•œ ฝ”๋“œฐ€ ๋‚˜™”๋‹ค. •˜ง€๋งŒ MonitorableStack€ pushMany •ˆ˜๋ฅผ ƒ†•œ‹ค. MonitorableStack„ ‚ฌšฉ•ด pushMany •ˆ˜๋ฅผ ˜œ•˜๋ฉด MonitorableStack˜ ž…๋ ฅ ๋ฐ›€ articles˜ articles.length ๋งŒผ pushฐ€ ˜œ๋œ‹ค. •˜ง€๋งŒ ง€ธˆ ˜œ๋œ push ๋ฉ”†Œ๋“œ๋Š” MonitorableStack˜ ฒƒด๋ผ๋Š”  ! ๋งค๋ฒˆ size() •ˆ˜๋ฅผ ˜œ•œ๋Œ€ ฌธฐ๋ฅผ ฐฑ‹ •œ‹ค. †๋„ฐ€ ๋А๋ งˆ ˆ˜๋„ žˆ๋‹ค. ธ๋ฆฌ  ๋งŒ•ฝ ๋ˆ„ตฐฐ€ Stack˜ ฝ”๋“œ๋ฅผ ๋ณด  pushMany •ˆ˜˜ ๋น„ šจœ„ฑ ๋•Œ๋ฌธ— Stack„ ๋ฐ‘˜ ฝ”๋“œ™€ ฐ™ˆ˜ •–ˆ๋‹ค๋ฉด –ด๋–ปฒŒ ๋  ฒƒฐ€???
class Stack {

 private int topOfStack = -1;

 private Object[] theData = new Object[1000]; 

 public void push(Object article) {

  theData[++topOfStack] = article;

 }

 

 public Object pop() {

  Object popped = theData[topOfStack--];

  theData[topOfStack] = null;

  return popped; 

 }

 

 public void pushMany(Object [] articles) {

  assert((topOfStack + articles.length) < theData.length);

  System.arraycopy(articles, 0, theData, topOfStack + 1, articles.length);

  topOfStack += articles.length;

 }

 

 public int size() {

  return topOfStack + 1;

 }

}
™€!~ ˜ˆ „˜ Stack๋ณด๋‹„ฑ๋Šฅ€ ™•‹žˆ ‹•„ กŒ„ ฒƒด๋‹ค. ธ๋Ÿฐ๋ฐ ๋ฌธ œฐ€ ๋ฐœƒ–ˆ๋‹ค. ๋”ƒ pushMany ๋ฉ”†Œ๋“œ—„œ push ๋ฉ”†Œ๋“œ๋ฅผ ˜œ•˜ง€ •Š๋Š”๋‹ค. ด๋ ‡ฒŒ ๋˜๋ฉด MonitorableStack€ ๋”ƒ Stack˜ œ๋Œ€ ฌธฐ๋ฅผ ถ” •˜ง€ ๋ชป•˜ฒŒ ๋œ‹ค. ˜ˆธฐ˜ •Š€ ฒฐณผด๋‹ค. ƒ†„ ‚ฌšฉ•œ ตฌ˜„œผ๋กœ ๋ฐœƒ•œ ๋ฌธ œด๋‹ค. —ฌธฐนŒง€ ธ€„ (ฑ…˜ ๋‚ดšฉ) —ˆ๋‹ค๋ฉด, •„๋งˆ 'ƒ†„ ‚ฌšฉ•˜ธฐ  „— •œ๋ฒˆ ๋” ƒฐ•˜๋Š”ฒŒ ‹ ‹ค' ๋ผ๋Š” ƒฐ„ ฐ€Šด นŠด ๋Аผˆ„ ฒƒด๋‹ค. •„‹ˆ๋ฉด ๋ณ„ˆ˜ —†๋Š” ด๋‹ค... :(

ž ธธ—ˆ๋˜ —ฌ–‰˜ ข…ฐฉ ด๋‹ค. œข… ฝ”๋“œ๋ฅผ ๋ณดž. œ„—„œ ๋ง–ˆ๋˜ ƒ†๋ณด๋‹ค๋Š” •„„... ƒ†๋ณด๋‹ค๋Š” „Ž˜ด๋ฅผ... ด๋ž€ ๋ง„ ข…••˜๋ฉด ...

"œ„ž„(•„ฑ)„ †ต•„Ž˜Šค๋ฅผ ตฌ˜„•˜ž." ๋ผ๋Š” ฒฐ๋ก ด ๋‚˜˜จ๋‹ค.


interface Stack {

 void push(Object article);

 Object pop();

 void pushMany(Object [] articles);

 int size();

}

 

class SimpleStack implements Stack {

 private int topOfStack = 0;

 private ArrayList theData = new ArrayList();

 

 public void push(Object article){

  theData.add(topOfStack++, article);

 }

 

 public Object pop() {

  return theData.remove(--topOfStack);

 }

 

 public void pushMany(Object [] articles) {

  for(int i=0; i<articles.length; ++i)

   push(articles[i]);

 }

 

 public int size() {

  return return theData.size();

 } 

}

 

class MonitorableStack implements Stack {

 private int maxHeight = 0;

 private int minHeight = 0;

 private SimpleStack stack = new SimpleStack(); 

 

 public void push(Object o) { 

  stack.push(0);

  if(stack.size() > maxHeight)

   maxHeight = size();

 }

 

 public Object pop() {

  Object poppedItem = stack.pop();

  if(size() < minHeight)

   minHeight = stack.size();

  return poppedItem;

 }

 

 public void pushMany(Object [] articles) {

  for(int i=0; i<articles.length; ++i)  

   push(articles[i]);

 

  if(stack.size() > maxHeight)

   maxHeight = stack.size();  

 }

 

 public int maximumSize() { return maxHeight; }

 public int minimumSize() { return minHeight; } 

 public int size() { stack.size(); }

}
™„„ฑ๋œ ฝ”๋“œ—„œ๋Š” ƒ†œผ๋กœ •œ ๋ฌธ œ๋“คด ๋ฐœƒ•˜ง€ •Š๋Š”๋‹ค.
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:24:03
Processing time 0.0198 sec