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

  

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
  

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. 
  
출처: http://stackoverflow.com/questions/285955/java-get-the-newest-file-in-a-directory


  

Reflection을 사용한 String Destroyer

Posted by epicdev Archive : 2011. 11. 16. 21:09
출처: http://snippets.dzone.com/posts/show/7920


출력 결과
Java World!

Note:
The original string ("Hello World") should be smaller or equal in size when compared to the new string ("Java World!") or else you will end up in ArrayIndexOufofBoundsException.

If the original string is smaller than the new string, then the new string will be truncated. In the above code if i use 'value.set("Hello World", "Java World$Rocks!".toCharArray());' then the output is 'Java World$'

If the original string is larger than the new string then you will end up in ArrayIndexOutOfBoundsException
Stack trace below:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
at java.lang.System.arraycopy(Native Method)
at java.lang.String.getChars(Unknown Source)
at java.io.BufferedWriter.write(Unknown Source)
at java.io.Writer.write(Unknown Source)
at java.io.PrintStream.write(Unknown Source)
at java.io.PrintStream.print(Unknown Source)
at java.io.PrintStream.println(Unknown Source)
at com.test.reflection.StringDestroyer.main(StringDestroyer.java:16)

I digged into String.java source code and found that there is a variable int count declared final. Once assigned, the value for count variable cannot be changed. The System.arraycopy(in the above exception) statement uses this count variable for copying the char array to another one. 
  
출력 결과
  

Java에서 현재 스택 상황을 보는 방법

Posted by epicdev Archive : 2011. 11. 16. 20:17
출력 결과
  
 «이전 1 2 3 4 5  다음»