OSGi 번들 상태 변화

사용자 삽입 이미지
Spring Dynamic Module for OSGi 1.0도 배포 되었고, 토비님께서 JCO에서 발표할 예정으로 되어 있는 Spring OSGi 재밌습니다.

본격적으로 공부를 시작하고 싶어서 레퍼런스를 조금 보고 있는데, 지금은 데이트를 하러 가야되서 이쯤에서 잠시 멈춥니다. 재밌습니다. 꺄호~ Spring Source 멋쟁이들.

참조 :
http://static.springframework.org/spring-osgi/snapshot-site/apidocs/index.html
http://www2.osgi.org/javadoc/r4/org/osgi/framework/Bundle.html
http://static.springframework.org/osgi/docs/current/reference/html/bnd-app-ctx.html

The Same But Different

1. Main Method

– Java와 C# 모두 메인 메소드가 진입점이다.
– C#의 메소드 작명 지침에 따라 Main 메소드 이름이 M 대문자로 시작한다.
– C#의 Main 메소드는 인자로 아무것도 안 가질 수 있다.

public static void Main() {}

– C#에서는 실행 파일 만들 때, /main 옵셥을 사용해서 집입점을 선택할 수 있다.
– 실행 파일의 이름이 소스 파일 이름과 달라도 되네.. 거의 Java의 JAR파일이랑 EXE랑 비슷하네..

사용자 삽입 이미지
2. Inheritance Syntax

– Java 처럼 상속은 extends, 인터페이스 구현은 implements 로 구분하지 않는다.
– 그냥 : 로 둘 다 나타낸다. 대신 인터페이스는 .Net 작명 지침 상 대문자 I를 클래스 이름 맨 앞에 붙여주니까, 인터페이스 구현인지 상속인지 구분 할 수 있다.

3. Run Time Type Identification (is operator)

– Java의 instanceof 연산자는 C#에서 is(짧아서 좋네.)

  if(x is MyClass)
   MyClass mc = (MyClass) x;

4. Namespaces

– Java의 package 이름은 물리적인 폴더 구조와 일치 해야 한다.
– C#의 namespace는 논리적인 구조를 나타내며, namespace안에 namespace를 추가할 수 있다.

    namespace Whiteship
    {
        public class A { }
        public class B { }

        namespace Sun
        {
            public class A { }
            public class B { }
        }
    }

5. Constructors, Destructors and Finalizers

– C#의 생성자는 Java의 생성자와 모양과 뜻이 같다.
– C#의 Destructor는 C++ 문법을 사용하지만 뜻은 Java와 더 비슷하다.(GC를 명시적으로 호출하지 않기 때문에 언제 호출 될지 예측할 수 없기 때문인가?)
– C#의 Destructor는 클래스 이름 앞에 ~를 붙인다.
– In C#, destructors(finalizers) automatically call the base class finalizer after executing which is not the case in Java.(???)

6. Synchronizing Methods and Code Blocks

– Java의 synchronized 블럭과 동일한 것을 C#에서는 lock 키워드를 사용한다.
– 동기화 메소드는 Java에서 synchronized 키워드를 메소드 이름 앞에 붙여주는데, C#에서는 [MethodImpl(MethodImplOptions.Synchronized)] 애노테이션을 붙인다.
– using System.Runtime.CompilerServices; 붙여 줘야 함.

7. Access Modifiers

– (참조 한 곳에서 Java의 접근 지시자를 잘못알고 있는 듯..)
– C#의 public은 Java의 public
– C#의 private은 Java의 private
– C#의 protected는 Java의 protected(상속 받은 클래스들에서 참조 가능)

– C#의 default는 private 이지만, Java의 default는 default(같은 패키지에서만 참조 가능)
– C#의 internal은 같은 assmbly에서만 참조 가능.
– C#의 internal protected는 같은 자기 자신과 assembly와 상속받은 클래스에서 참조 가능.

8. Reflection

– C# is done at the
assembly
level while reflection in Java is done at the
class level.
– C#은 타겟 클래스를 담고 있는 DLL 파일이 필요해.
– Java의 Class는 C#의 Type

Type type = typeOf(MyClass);

– 동적으로 생성되는 타입은 어떻게 알아내지?

ICollection a = new ArrayList();
Type type = typeOf(a); //이런건 안되던데;;

9. Declaring Constants

– Java는 컴파일 시점에 설정거나 실행중에 설정할 상수 모두를 final로 나타낸다.
– C#에서 컴파일 시점에 설정할 상수는 const 키워드를 사용하고 실행 중에 설정할 상수는 readonly  키워드를 사용한다.
– primitive 타입 상수와 reference 타입 상수에 대한 개념은 Java와 동일하다.
– Java에서는 메소드의 파라미터도 final을 붙일 수 있는데 C#에서는 그런 기능이 없다.(그럼 C#은 inner class에 참조 할 때 final 안붙여도 상관없나..)

10. Primitive Types

– Java의 byte 는 C#에서 sbyte
– C#에서는 unsigned 타입을 제공한다. uint, ulong, ushort, byte
– C#에서는 decimal 타입을 제공한다. 더 정확하고 더 많은 공간과 시간을 소비한다. 값뒤에 d를 붙여준다.

11. Array Declarations

– C#에서는 다음과 같은 문법으로만 배열을 생성할 수 있다.
int[] iArray = new int[100];
– Java에서는 아래처럼 해도 되지만, C#에서는 안 된다.
float fArray[] = new float[100];

12. Calling Base Class Constructors and Constructor Chaining

– Java와 마찬가지로 상위 클래스의 생성자 호출은 제일 먼저 실행되어야 한다.(그래야 초기화 되지 않은 변수를 가져다 쓰는 일이 벌어지지 않을테니까..)
– 생성자 안에서 자기가 가지고 있는 다른 생성자를 호출하는 것을 Constructor Chaining 이라고 한다.
– 생성자 바디에 넣는게 아니라 아예 메소드 시그너쳐 바로 옆에 붙여주는 군..

MyException(string message): this(message, null){}
MyException(string message, Exception innerException): base(message, innerException){}

13. Variable Length Parameter Lists

– 가변인자를 Java에서는 … 을 사용해서 여러개의 파라미터를 배열에 받아 올 수 있다.
– C#에서는 params 키워드를 사용하며 배열 타잎 앞에 붙여준다.

public void printTitleAndNums(string title, params int[] nums){}

14. Generics

– Although similar in concept to templates in C++, the Generics feature in C# and Java is not implemented similarly

– Java는 type erasure(컴파일 이후에는 Generic을 삭제하고 Object 타입으로 동작한다. 알아서 해당 타입으로 캐스팅 해준다.)를 사용해서 generic 기능을 구현했다.
– 기존 코드legacy code와의 호환interoperability 때문에 이렇게 구현했다.
    –  런타임 시에 타입을 알 수 없다는 단점이 있다. 리플랙션으로 알아낼 수가 없다.
    – 항상 객체 타입이어야 한다. 따라서 정수형이 필요할 때, Collection<int>가 아니라 Collection<Integer>를 사용해야 한다.

– C#은 .NET 런타임의 Instruction Language(IL)의 지원을 받는다. Generic 타입이 컴파일 되면, 만들어진 IL이 특정 타입에 대한 Placeholder를 가지고 있다. Generic 타입에 대한 레퍼런스 초기화 요청이 오면 Placeholder에 해당 타입이 있는지 확인하고 있으면, 그것을 돌려주고 없으면 Generic 타입 파라미터를 요청한 타입으로 바꿔준다. 이때 요청 받은 타입이 Reference 타입일 경우에는 Generic 타입 파라미터를 Object로 바꿔주지만, 해당 타입에 접근할 때 캐스팅을 하지는 않는다.(캐스팅 하지 않고도 해당 타입의 멤버에 접근할 수가 있나..??)
=> C#은 value 타입을 Generic 타입으로 사용할 수 있다.
=> C#은 런타임시에 Generic 타입을 알 수 있다.

– Java의 와일드카드 타입 ? 은 C#의 generic type inferencing

– C#와 Java 모두 Generic 타입에 제약을 가할 수 있다.
    – derivation constraint: 하위 제한으로 특정 인터페이스나 클래스를 구현하거나 상속받은 클래스로 제한하기
    – default constructor constraint:  public 기본 생성자를 가진 클래스로 제한
    – reference/value type constraint constrains: Generic 타입 파라미터를 reference나 value 타입으로 제한.

– C#은 default 연산자를 제공한다. reference 타입은 null, value 타입은 0과 공백을 리턴한다.

15. for-each Loop

– 배열이나 System.Collections.IEnumerable를 구현한 클래스 타입을 간단하게 순회할 수 있다.
– C#에서는 foreach  와 in을 사용한다.

foreach(int num in nums)
Console.WriteLine(num);

16. Metadata Annotations

– [MethodImpl(MethodImplOptions.Synchronized)]: 동시에 여러 쓰레드가 해당 메소드를 사용하는 것을 막기 위해서 사용.
– [Serializable]: Java의 Serializable 인터페이스와 같은 효과.
– [FlagsAttribute]: 비트와이즈 연산을 지원해야 한드는 의미로, Enumerarion위에 붙여준다.
– [WebMethod]: ASP.NET에서 사용하는데, 이걸 메소드 위에 붙이면 자동으로 웹에서 웹 서비스로 사용할 수 있다.
– 리플랙션을 사용해서 모듈, 클래스, 메소드, 필드에 붙어있는 어트리뷰트에 접근하는 것이 가능하다.(자바도 가능)
– System.Attribute 클래스를 상속해서 원하는 어트리뷰트를 만들 수도 있다.

– Java는 Meta Annotation을 만들 수 있지만, C#은 못한다.

17. Enumerations

– Java의 Enum은 Type-Safe하고, 필드와 메소드를 추가할 수 있고, 인터페이스를 구현하는 것도 가능하다.
– C#에서는 그냥 int 값이다. 따라서 Type-Safe하지 못하다.
– Console.WriteLine()으로 찍으면 문자로 찍히는데.. int 값을 Enum 타입으로 형변환 해버릴 수 있다. 그런 다음에 찍으면 숫자가 찍힌다.

The More Things Change The More They Stay The Same

참조 : A COMPARISON OF MICROSOFT’S C# PROGRAMMING LANGUAGE TO SUN MICROSYSTEMS’ JAVA PROGRAMMING LANGUAGE

1. We Are All Objects

– java.lang.Object와 비슷한 클래스 System.Object
– 모든 클래스들의 슈퍼 클래스.
– 메소드 이름이 대문자로 시작하는 군.
– object 키워드 == System.Object

2. Keyword Jumble

– 자바에는 없는 키워드가 C#에는 많이 있군.
자바 -> C#
extends, implements -> :
boolean -> bool
final -> sealed
protected -> internal (C#의 protected는 다른 의미인듯..)

3. Of Virtual Machines and Language Runtimes

– 자바 소스 코드 -> 바이트 코드 -> Run in JVM
– C# 소스 코드 -> IL(Intermediated Language) -> Run in CLR(Common Language Runtime)

4. Heap Based Classes and Garbage Collection

– 자바는 new 키워드를 사용해서 모든 객체를 힙 영역에 생성.
– C#도 new 키워드를 사용해서 일부 클레스의 객체를 힙 영역에 생성.
– JVM 처럼 CLR도  Mark and Compact garbage collection algorithm 사용해서 Gabage Collection을 수행한다.
– value 타입은 stack에 생성할 수도 있나보다.

5. Arrays Can Be Jagged

– C나 C++의 다차원 배열에서 배열은 꼭 같은 길이의 배열을 가져야 했다.
– C#과 Java는 배열이 다른 길이의 배열을 가지고 있어도 된다.
int [][]myArray = new int[2][];
myArray[0] = new int[3];
myArray[1] = new int[9];

6. No Global Methods

– C++ 에서는 메소드가 클래스 밖에 있어도 됐나보다.
– C#은 자바처럼 메소드가 클래스의 멤버나 Static Method여야 한다.

7. Interfaces, Yes. Multiple Inheritance, No

– Java처럼 인터페이스는 다중 상속(구현)을 허용.
– Java처럼 상속은 다중 상속을 허용하지 않음.

8. Strings Are Immutable

– C#의 System.String은 Java의 java.lang.String과 비슷. 변하지 않는다.
– C#의 System.Text.StringBuilder는 Java의 java.lang.StringBuffer과 비슷.(동기화 시켜놓은 것도 비슷하려나;; 안했으면 StringBuilder랑 비슷한건데..)
– string 또는 String으로 표기할 수도 있다.

9. Unextendable Classes

– 자바에서 final 키워드를 class 앞에 붙이면 더이상 상속하지 못하는 클래스가 된다.
– C#에서는 sealed 키워드를 class 앞에 붙이면 된다.

10. Throwing and Catching Exceptions

– 자바와 동일하게 예외 클래스들의 최상위에 Exception 클래스를 제공한다.
– 예외를 감싸서 다시 던질 수 있다.

11. Member Initialization at Definition and Static Constructors

– 만약 멤버 변수가 인스턴스 변수이면, 생성자가 호출되기 전에 초기화 한다.
– Static 멤버들은 해당 멤버를 사용하기 전이나, 멤버가 속해있는 클래스의 객체를 만들기 조금 전에 초기화 한다.
– 인스턴스 변수를 생성하거나 Static 메소드를 호출하기 전에 특정 블럭을 실행하도록 하는 것도 가능하다.
– 자바에서는 이런 코드 블럭을 static 초기화 블럭이라고 한다.
– C#에서는 static 생성자라고 한다.(실제 모양도 생성자 모양.)

using System;

class StaticInitTest{

    string instMember = InitInstance();

    string staMember = InitStatic();
   

    StaticInitTest(){
    Console.WriteLine(“In instance constructor”);
    }

    static StaticInitTest(){
    Console.WriteLine(“In static constructor”);
    }

    static String InitInstance(){
    Console.WriteLine(“Initializing instance variable”);
    return “instance”;
    }

     static String InitStatic(){
    Console.WriteLine(“Initializing static variable”);
    return “static”;
    }

    static void DoStuff(){
    Console.WriteLine(“Invoking static DoStuff() method”);
    }

   
    public static void Main(string[] args){

    Console.WriteLine(“Beginning main()”);

    StaticInitTest.DoStuff();
   
    StaticInitTest sti = new StaticInitTest();

    Console.WriteLine(“Completed main()”);

    }

}

In static constructor
Beginning main()
Invoking static DoStuff() method
Initializing instance variable
Initializing static variable
In instance constructor
Completed main()

이런 코드가 나온이유.

main() 메소드 실행하기 전에, static 생성자가 호출 된다.

In static constructor

그 다음 static 메소드를 호출할 때는 이미 static 생성자가 호출 됐기 때문에 그냥 메소드 호출.

Invoking static DoStuff() method

생성자가 호출되기 전에 인스턴스 변수들을 초기화 하기 때문에, new StaticInitTest(); 하는 순간 필드들을 초기화 하려고 하겠지.. 그래서..

Initializing instance variable
Initializing static variable

12. Boxing

– .Net은 boxing, unboxing 그냥 된다.
– Java도 5 부터는 된다.
– C#에서도 Collection에는 객체만 들어갈 수 있군.

Eclipse에서 Static Import 편하게 쓰려면

Java 5에 추가된 static import 기능을 사용할 때 보통 .* 로 모든 Static Method들을 클레스 이름을 붙이지 않고도 사용할 수 있습니다. .* 대신에 사용할 메소드를 import 해도 되지만… import문이 여러개로 늘어나는데다가, 무엇보다 자동완성이 지원되지 않아서 불편합니다. 특히 JUnit4로 테스트를 작성할 때 그렇쵸.

문제는

import static org.junit.Assert.*;

이렇게 한 줄 추가(이것 마저도 퀵픽스Ctrl + 1를 사용하면 외우지 않아도 됩니다.)한 뒤 코딩을 하다가 버릇처럼 Ctrl + Shift + O를 한 번씩 눌러주면, 다음과 같이 바뀐다는 것입니다.

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

이 다음 부터는 이제 자동완성도 안 되고, 그러면 assertTr 까지만 입력해도 되는 걸 assertTrue(1 == result); 이렇게 전부 입력한 다음에 퀵픽스로 임포트 문을 또 추가해줘야 합니다. 귀찮죠..

그래서 Ctrl + Shift + O 를 입력할 때, .*로 전부 묶을 수 있습니다.

사용자 삽입 이미지
위와 같이 Number of static import needed for .* 을 99에서 1로 수정해주시면 Ctrl + Shift + O 로 import문을 정리할 때 .* 만 남기고 그 이하는 모두 제거합니다.

사용자 삽입 이미지
그럼 이제 ‘import문 정리하기’를 한 뒤에도 자동완성으로 다른 static 메소드들을 사용할 수 있습니다.

99% Line Coverage

몇일전 기록한 98% Line Coverage 기록을 깨습니다. 이제 남은 건 100% Line Coverage 뿐이군요.

사용자 삽입 이미지
볼링 게임을 구현한 것인데, 완성하는데 하루가 걸렸습니다. 아 어제 이맘때부터 계속 머릿속을 괴롭히던 녀석을 처리하니 피곤이 몰려오는 것 같습니다.

볼링 게임이 매우 간단한 것 같은데, Stike, Spare 점수 계산 그리고 마지막 프레임의 특이함 때문에 코드가 금방 지져분해집니다.

만들면서 느낌점을 요약했는데, 다음과 같습니다.

느낀점.
– 어떤 테스트를 통과Pass 하게 만들려다가 그 전에 먼저 작성해야 할 메소드가 생긴다.
    – 이 때는 지금 하던 걸 멈추고 사전에 먼저 작성해야 할 것 부터 만들자.
    – @Ignore
– 테스트를 잘못 작성하면 구멍이 생긴다.
    – 테스트를 작게 잘 작성하자. 하나의 Task가 5분을 넘기지 말아야 한다.
    – 어떻게 하면 구멍이 생기지 않는 테스트를 작성할 수 있을까?
– 객체 지향 기본 원칙 지키며 코딩하는게 정말 어렵다.
    – 코딩하다보면, 어느새 객체 지향 원칙은 안중에도 없어 진다. 사실 잘 발견을 못한다.
    – 변하는 부분과 변하지 않는 부분을 분리하라.
    – 어떻게 하면 자연스럽게 패턴이 튀어나올까?