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