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.0193 sec