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