리팩토링입문
카테고리 컴퓨터/IT > 프로그래밍/언어
지은이 히로시 유키 (한빛미디어, 2007년)
상세보기

  
상속을 사용해서 좋은지 나쁜지를 판단할 때에는 리스코프의 치환원칙을 사용합니다.

FUNCTIONS THAT USE POINTERS OR REFERENCES TO BASE
CLASSES MUST BE ABLE TO USE OBJECTS OF DERIVED CLASSES
WITHOUT KNOWING IT.

Child 클래스가 Parent 클래스의 서브클래스라고 해봅시다.

리스코프의 치환원칙은 "Parent형의 변수에 Child 클래스의 인스턴스를 대입해도 문제없이 사용할 수 있다" 라는 원칙입니다.

위 처럼 Parent를 상속받은 Child의 인스턴스로 Parent의 메소드인 foo나 bar를 호출해도 아무런 문제없이 잘 실행이 되어야 한다는 것입니다.

그런데 만약 Child에서는 foo라는 메소드는 제대로 구현이 되지 않아서 UnsupportedOperationException이 throw 되도록 구현해 놓았다면

이는  리스코프의 치환원칙에 위배되는 것입니다.

참고:  http://www.objectmentor.com/resources/articles/lsp.pdf 


리팩토링입문
카테고리 컴퓨터/IT > 프로그래밍/언어
지은이 히로시 유키 (한빛미디어, 2007년)
상세보기
 
  

Chain Constructors (연쇄 생성자)

Posted by epicdev Archive : 2012. 1. 24. 23:04

디폴트 생성자에서 rand = new Random(DEFAULT_SEED);를 호출하지 않고
long seed를 인자로 받는 다른 생성자를 호출하는 방식을 통해 중복되는 코드를 피하고 있다. 
  

Dependency Injection (의존성 주입)

Posted by epicdev Archive : 2012. 1. 24. 20:29
출처:  http://jamesshore.com/Blog/Dependency-Injection-Demystified.html 

 When I first heard about dependency injection, I thought, "Dependendiwhatsit?" and promptly forgot about it. When I finally took the time to figure out what people were talking about, I laughed. "That's all it is?"

"Dependency Injection" is a 25-dollar term for a 5-cent concept. That's not to say that it's a bad term... and it's a good tool. But the top articles on Google focus on bells and whistles at the expense of the basic concept. I figured I should say something, well, simpler.

The Really Short Version

Dependency injection means giving an object its instance variables. Really. That's it.

The Slightly Longer Version, Part I: Dependency Non-Injection

Classes have these things they call methods on. Let's call those "dependencies." Most people call them "variables." Sometimes, when they're feeling fancy, they call them "instance variables."

public class Example { 
  private DatabaseThingie myDatabase; 

  public Example() { 
    myDatabase = new DatabaseThingie(); 
  } 

  public void DoStuff() { 
    ... 
    myDatabase.GetData(); 
    ... 
  } 
}

Here, we have a variable... uh, dependency... named "myDatabase." We initialize it in the constructor.

The Slightly Longer Version, Part II: Dependency Injection

If we wanted to, we could pass the variable into the constructor. That would "inject" the "dependency" into the class. Now when we use the variable (dependency), we use the object that we were given rather than the one we created.

public class Example { 
  private DatabaseThingie myDatabase; 

  public Example() { 
    myDatabase = new DatabaseThingie(); 
  } 

  public Example(DatabaseThingie useThisDatabaseInstead) { 
    myDatabase = useThisDatabaseInstead; 
  }

  public void DoStuff() { 
    ... 
    myDatabase.GetData(); 
    ... 
  } 
}

That's really all there is to it. The rest is just variations on the theme. You could set the dependency (<cough> variable) in... wait for it... a setter method. You could set the dependency by calling a setter method that's defined in a special interface. You can have the dependency be an interface and then polymorphically pass in some polyjuice. Whatever.

The Slightly Longer Version, Part III: Why Do We Do This?

Among other things, it's handy for isolating classes during testing.

public class ExampleTest { 
  TestDoStuff() { 
    MockDatabase mockDatabase = new MockDatabase(); 

    // MockDatabase is a subclass of DatabaseThingie, so we can 
    // "inject" it here: 
    Example example = new Example(mockDatabase); 

    example.DoStuff(); 
    mockDatabase.AssertGetDataWasCalled(); 
  } 
}

public class Example { 
  private DatabaseThingie myDatabase; 

  public Example() { 
    myDatabase = new DatabaseThingie(); 
  } 

  public Example(DatabaseThingie useThisDatabaseInstead) { 
    myDatabase = useThisDatabaseInstead; 
  } 

  public void DoStuff() { 
    ... 
    myDatabase.GetData(); 
    ... 
  } 
}

That's it. Dependency injection is really just passing in an instance variable.

Further Reading

There's a lot of ways to make this simple concept very complicated. (There's lots of ways to make any concept complicated! Simplicity is hard.) Sometimes such complexity is necessary... and it's never my first choice. I've chosen not to discuss those bells and whistles here, but if you really want to know, check out these resources:

  • Inversion of Control Containers and the Dependency Injection Pattern. Martin Fowler is my favorite author. Usually he's clear and concise. Here he succeeds in making dependency injection sound terribly complicated. Still, this article has a thorough discussion of the various ways dependency injection can be tweaked.

  • A Beginner's Guide to Dependency Injection. This article is more about "DI containers" than it is about dependency injection itself. It takes a simple example and shows how it could be implemented using multiple off-the-shelf containers. I'm left wondering what the value is, but I'm a heretic, so feel free to ignore me on this one. Still, you have to marvel at any approach that takes three concepts ("TripPlanner," "CabAgency," and "AirlineAgency"), turns them into nine-plus classes, and then adds dozens of lines of glue code and configuration XML before a single line of application logic is written.

  

Enum을 사용한 State 패턴

Posted by epicdev Archive : 2012. 1. 24. 20:03

  

'Archive' 카테고리의 다른 글

Dependency Injection (의존성 주입)  (0) 2012.01.24
Enum을 사용한 State 패턴  (0) 2012.01.24
한글 띄워쓰기 쉽게 교정하는 방법  (1) 2012.01.17
Eclipse에서 Shift + Enter 기능  (0) 2012.01.15
Javadoc에 @link로 링크걸기  (0) 2012.01.15
  

한글 띄워쓰기 쉽게 교정하는 방법

Posted by epicdev Archive : 2012. 1. 17. 07:51
한글로 블로깅을 할 때 띄워쓰기가 헷갈릴 경우가 많다.
이럴때 내가 사용하는 서비스이다.

네이버에서 현재 테스트중인 서비스 중에 자동 띄워쓰기라는 서비스가 있다.
아래의 주소로 들어가서 이용하면 된다.
http://s.lab.naver.com/autospacing 

아래와 같이 사용하면 주소창에서 곧바로 입력도 가능하다
http://s.lab.naver.com/autospacing/?query=자동띄워쓰기서비스를+이용해봅시다



크롬을 사용할 경우 이를 응용해서 검색엔진 설정을 해놓으면, 
더 간편하게 사용가능하다
(query= 뒷부분을 %s로 바꾸면 된다)

 


내용 추가 (2012.09.28)


생각보다 띄어쓰기로 검색하셔서 제 글을 보시는 분들이 많으신 것 같아서 내용을 추가합니다.
저는 요즘 네이버 자동 띄어쓰기보다 부산대학교의 '한국어 맞춤법/문법 검사기'를 더 자주 사용합니다.
부산대학교의 한국어 맞춤법/문법 검사기의 경우 띄어쓰기 뿐만 아니라
문법 또한 검사해주고 왜 틀렸는지 자세히 설명도 해주기 때문에 매우 유용합니다.







  

Eclipse에서 Shift + Enter 기능

Posted by epicdev Archive : 2012. 1. 15. 21:53
Eclipse에서 Shift + Enter를 누르면 커서가 어디에 있건 바로 아랫줄에 빈라인을 만들어주고 그 위치로 커서가 이동한다.
별것 아닌것 같은 기능이지만서도, 정말 편리하다.
이 기능이 없으면 end를 누르고 enter를 쳐야되지만 이 기능을 사용하면 오른손을 end까지 움직이지 않고 위의 동작이 가능하다. 
  

Javadoc에 @link로 링크걸기

Posted by epicdev Archive : 2012. 1. 15. 19:12
Javadoc을 쓸때 다른 클래스로의 링크나 JUnit테스트 케이스로 링크할 때 유용합니다
Eclipse에서 작업할때는 컨트롤 누르고 링크 클릭하시면, 링크로 이동됩니다.

예: {@link FileWriter#append(char)}
  
출처:  http://user.xmission.com/~goodhill/dates/datedeprecation.htm 

Is java.util.Date Deprecated?

by Paul Hill, August 2004

If you look at java.util.Date, you will find that most of it is deprecated. This makes you wonder if the intent is for Java programmers to use something else instead. You might guess that you should be using java.util.Calendar. This turns out to not be the case.

Looking at java.util.Dates we see that of its 6 constructors, only two are not deprecated. Of the 28 methods of the class, 8 are not deprecated, and of those, 5 override the standard methods of java.lang.Object -- toString(), hashCode(), clone(), compareTo(Object o)and equals(Object obj) -- one of the others is a simple variation of compareTo -- compareTo(Date anotherDate). All this leaves is getTime(), setTime(long time), Date() and Date(long date).

A Role for java.util.Date

It looks like nothing remains for java.util.Date to do. So should we leave it for dead and go on to other things? No, java.util.Date still has an important role. A java.util.Date is a value object. Another way to think about a java.util.Date is that it is a variation of the Memento or Token pattern. It simply holds state -- a value. It serves somewhat the same role java.lang.Integer; it's just a typed container.

It is worth noting that java.util.Date is not made up a series of fields representing year, month, day etc., but is a long integer value of milliseconds since 1970-01-01 00:00:00.00 GMT. This is a very compact way to represent a date and time value, thus fits the idea of the Memento pattern very well. Looking again at the remaining methods and constructors all we see are methods for creating Dates with a millisecond value and getting that millisecond value. Such a simple object is useful for passing around, which is why various methods in the API still take Date, not because they are as old as the Date class, but because they only need a simple date-time binary value.

Maybe the most common use of Date is in JDBC. The JDBC libraries represent dates (no time of day), timestamps (a timestamp possibly down to the nanoseconds) or time (just a time value) using subclasses of java.util.Date. The JDBC does not take or return Calendars in as object that holds a date-time or timestamp.

You should use a java.util.Date to hold timestamps when you need to move such values between different parts of your software.

A Role for java.util.Calendar and java.util.GregorianCalendar.

Given the argument above for java.util.Date, you might ask what then is the role of java.util.GregorianCalendar, the implemenation in standard libraries of the abstract class java.util.Calendar? GregorianCalendar is a variation of a strategy pattern "A strategy is an algorithm" 1. The GregorianCalendar is an algorithm for converting a moment in time to a particular year, month, day, hour, minute, second etc. In order to do this, the GregorianCalendar must know which timezone to use which will also include when the daylight savings begins. It might need to know such bits of arcane knowledge as when the older Julian calendar switched to the Gregorian calendar. GregorianCalendar also contains an array of values for holding all of the various fields it knows how calculate. All of this additional information as part of its extensive internal state, makes GregorianCalendar many tens of times larger than the much simplier java.util.Date.

Separating out the algorithm from the simple state allows us to replace one strategy with another. If you needed to calculate the year, month and day and year fields of another calendar you could use a different implementation of java.util.Calendar. There are various implementations of calendar available including ChineseCalendar, HebrewCalendar, and IslamicCalendar available from the IBM ICU4J Project.

What about SimpleDateFormat?

You might be thinking that the there is a third option, java.text.SimpleDateFormat. What you will find is that this class uses a java.util.Calendar just as it should use a strategy. Internally, SimpleDateFormat uses a Calendar for all date calculations. It is also true that when you call Date.toString(), you are also using a Calendar -- the default calendar -- to calculate date fields.

Summary

java.util.Date might look as if it is on its last legs and should be relegated to history, but it continues to have a vital role as a value object or memento which holds a date-time stamp. It should not be replaced with Calendar and its subclasses, but used in conjuntion with those classses. 
  
 «이전 1 ··· 4 5 6 7 8 9 10 ··· 17  다음»