'구구단' 검색 결과 2건

  1. 2008.11.05 객체지향적 구구단 (3)
  2. 2008.11.05 I'm a boy. You're a girl. (3)
아래 글들에서 구구단 얘기좀 쓰다보니 갑자기 불현듯 생각이 나서 하나 더 씁니다. ㅎㅎ

객체지향적 구구단이라거나 객체지향적 Hello World에 대한 이야기를 간혹 보게 되는데 과연, 객체지향적으로 잘 설계된 구구단이란게 뭘까요?

아니, 객체지향이고 뭐고를 떠나서, 잘 설계된 구구단이란 뭘까요?

Uncle Bob이 "Agile Software Development"라는 책에 쓴 구절을 인용하는게 좋겠습니다:
(발번역입니다 --; ) LSP에서 중요한 결론을 한 가지 얻을 수 있다: 모델만 따로 보아서는 결코 적절성을 논할 수 없다. 해당 모델을 사용하는 코드의 입장에서 보았을 때에만 적절성을 이야기할 수 있는 것이다.

(중략)

특정 설계가 적절한가 그렇지 않은가에 대해서 그 설계만 놓고서는 알 수 없다. 해당 설계를 사용하는 측으로부터 도출되는 타당한 가정들에 기반하여 평가해야 한다. (단위 테스트가 이러한 가정들을 명시적으로 선언하는 역할을 한다. 이는 TDD의 또 다른 장점이다)

The Liskov Substitution Principle leads us to a very important conclusion: A model, viewed in isolation, cannot be meaningfully validated. The validity of a model can only be expressed in terms of its clients.

(...omitted...)

When considering whether a particular design is appropriate or not, one cannot simply view the solution in isolation. One must view it in terms of the reasonable assumptions made by the users of that design(Often you will find that those reasonable assumptions are asserted in the Unit Tests written for the base class. Yet another good reason to practice Test Driven Development).

--p116

그럼 다시. 구구단을 최대한 잘 설계하라고 할 때 어떠한 답을 내놔야 할까요? 저라면 이렇게 짜겠습니다:
public class Gugu {
    public static void main(String args[]) {
        for (int i = 2; i <= 9; i++)
            for (int j = 1; j <= 9; j++)
                System.out.println( i + " * " + j + " = " + (i * j) );
    }
}

스스로 평가를 해보자면:
  • 상속성: 모듈이 하나라 상속 필요 없음
  • 캡슐화: 모듈이 하나라 캡슐화 필요 없음
  • 은닉: 모듈가 하나라 숨길 필요 없음

많은 사람들이 제일 중요한 덕목으로 쳐주는 재활용성(ㄷㄷㄷ)의 측면에서 보자면:
  • 재활용성: 어디에 "다시 쓰일지(re-use)" 예측할 수 있는 정보가 없으므로, 가장 단순하게 작성하였음. 코드가 짧고 명확하니 최소한의 수정비용으로 최대한 다양한 곳에 활용될 수 있음.

이렇다고 생각합니다.

신고

I'm a boy. You're a girl.

나쁜 코딩 - 약한 결합을 위해 추상클래스를 선언했지만...

이 글... 은근히 좋은 화두가 되는군요. ^^

위 글에 인용된 한 학생의 코드는 여러가지 객체지향 설계의 원칙들 혹은 그 이전에 구조적 프로그래밍의 원칙들을 어기고 있습니다(사실은 이 둘이 별로 다르지도 않지만).

과제가 뭐였길래 저런 결과가 나왔을까요? 아마도, 계산 로직은 동일하고 출력만 다르게 하는 것이 요구사항이었던 것 같습니다. 그리고... "상속과 추상 클래스를 사용할 것" 같은 제약이 있었을 것 같기도 하고요.

이렇게 추측한 요구사항을 가지고 대충 고쳐보자면 전 아마 이런식으로 했을 것 같아요:
abstract class Computer {
  void print() {
        for (int i = 2; i <= 9; i++)
            for (int j = 1; j <= 9; j++)
                System.out.print( i + " * " + j + " = " + (i * j) + this.getSeparator());

        System.out.println(this.getName());
  }
  abstract String getName();
   abstract String getSeparator();
}
class Linux {
   public String getName() {return "Linux";}
   public String getSeparator() {return "\t";}
}
class Window {
   public String getName() {return "Window";}
   public String getSeparator() {return "\n";}
}

// main은 생략.

그런데 말이죠, 위 코드는 과연 얼마나 현실적인가요?

전 이런 코드를 보면 "I'm a boy. You're a girl." 같은 영어 문장이 생각납니다. 올바른 문장이기는 하지만 평생 실생활에서 쓸 일이 없고, 대체 어떤 상황에서 저런 대사가 나오는지 짐작조차 할 수 없는 그런 문장 말이죠.

과제의 조건이 좀 더 그럴듯했다면, 즉 억지로 상속과 추상 클래스를 사용하는 것이 아니라 실제로 상속과 추상 클래스를 썼을 때 깔끔하게 풀릴만한 조건이 과제로 제시되었다면 어땠을까요? 좀 더 나은 코드가 나오지 않았을까 싶어요. 코드 리뷰를 하면서 잘못된 부분을 지적해줄 때도 좀 더 쉽게 납득할 수 있지 않았을까요?

(비현실적인 예제가 무조건 나쁜 것은 아니라고 생각해요. 예를 들어 이런 종류의 과제는 참말 훌륭하다고 생각합니다.)

신고
< Newer     Older >

티스토리 툴바