MIT에서 선정한 앞으로 미래를 주도할  10가지 기술중에 하나가 AOP (Aspect Oriented Programming)라고 하는 넘이 있다.

어느 머리 좋은분이 여기에다가 "관점지향프로그래밍"이라고 가져다 붙였는데 사실 AOP자체가 OOP를 보완발전시키기 위해 나온개념이다보디 "객체지향~어쩌구"를 "관점~어쩌구로"싹 바꿔버린 번역 되겠다.

AOP라고 하는것이 그리 대단한것이 아니다.

"Object"로 쪼게고 쪼게다 보니 Object와 Object의 공통모듈을 따로 만들어 호출해야 했다.

가령 공통모듈 속에 있는 "excute()"라는 메소드를 모든 객체에서 실행해야 한다고 치자.
이경우 기존에는 A객체, B객체, C객체 등등등 에서 상속을 받던가 위임하여 실행하여야만 했다.
그러다가 "execute()"메소드 속성이 변경되거나 하면 그야말로 끔찍하게도 모든 객체를 다 열어서 수정해줘야만 했다.
이러면서 듣는소리는 "그러길레 설계를 첨부터 잘하지" 라던가...
"야야~~ 봐봐 내가 시킨대로 짜지 왜 삽질해?"라던가...
속으로 "아18 니미~~~" 등등등 온갖 혼잦말과 잔소리를 들어야 했지만 AOP개념이 탑재된 똑똑한 프레임워크 위에서라면 이런 걱정 안하고 코딩해도 된다는 이야기!
그게 AOP이다.

다시말해 AOP개념이 탑재된 프레임워크는 이러한 공통모듈을 Joint Point(접합점)을 호출만하면 알아서 공통모듈 인터페이스를 만들어주고 알아서 다 실행해준다.

결론적으로 AOP는 일반 프로그래머가 공통모듈에 신경쓰지 않고 주어진 목적(Object)에만 전념할 수 있는 환경을 만들어 준다는 개념이라는 것이다.

프로그래머들이여~ 우리보다 똑똑한 프레임워크 만드는 사람에게 이런것 고민하라고 하고 우리는 그냥 도사들이 만들어준 편리한 환경에서 코딩이나 하자 ^^

* 참고 사이트
MSDN : http://www.microsoft.com/korea/msdn/li ··· cle.aspx
.NET 스프링 프레임워크 : http://www.springframework.net/
자바 스프링 프레임워크 : http://www.springframework.org/

2007/04/05 13:51 2007/04/05 13:51

지난번에 자료구조(http://www.wolfpack.pe.kr/87 참조)에 대해 이야기했었는데 오늘은 MS가 여러사람 괴롭혔던 박싱(Boxing)과 언박싱(Unboxing)에 대해 이야기 해보자.

이전 자료구조를 들여다 보면 메모리에 힙과 스택이 있다고 했다.
힙은 그냥 막쓰는 메모리고 스택은 지정한 크기만큼 사용하는 메모리 공간이라고 했었다.
또한 스택은 int형과 같이 형(Type)선언과 동시에 크기가 결정되는 데이터형이 들어간다고 했고 힙은 String과 같이 형(Type)만 선언되고 크기가 결정되지 않는 것들이 들어간다고 했었다.
정확하게 이녀석들을 따져보면
int,byte,char,single,double,boolean,decimal과 같은 녀석들이 바로 스택을 사용하는 Value Type이다.
String, Array, Object, Class, Interface, Delegate과 같은 녀석들은 힙을 사용하는 Reference Type이라고 한다.

뭐 이리 복잡하게 나눠놨냐만은 실재 메모리 사용을 보면 좀더 이해가 쉬우려나?
int a = 0; 이라고 하면

메모리주소 : [0]
라고 메모리 주소에 값 "0"이 들어간다.

그러나 string a = "1234";라고 하면

메모리주소 : [참조하는메모리주소] - 참조된메모리주소 : [1234]
와 같이 할당되는 메모리의 주소에 값은 없고 실재 값이 있는 메모리 주소가 들어간다.

그래서 위에 넘은 Value타입이라고 하고 밑에 넘은 Reference타입이라고 한다.

* 너무 원망말자. 내가 만든 개념이 아니라 공부 많이한 사람들이 만든 개념이니...

이제 본론 박싱(Boxing)은 그럼 뭘까?
바로 Value타입을 Reference타입으로 변환하는 것을 말한다.
코드를 보자

using System;

class Test {   public static void Main() {     int a = 1;     object b = a; //요걸 박싱되었다고 한다.      //또는 이렇게 변환도 가능하다.       /*         string b = a.ToString();        */     Console.WriteLine (b);   } }


언박싱(Unboxing)은 반대개념이다. 즉, Reference타입을 Value타입으로 바꾸는 작업을 말한다.
using System;

class Test {   public static void Main() {     int a = 1234;     object b = a; //박싱하다     int c = (int)b; //언박싱하다     Console.WriteLine (c);   } }


쩝.. 한가지 불만이 있다면 value 타입에서 Reference타입으로 변환할때 중간에 Object 타입으로 변환해야 한다는거 그거 되겠다.

아무튼 이런 구조를 알아서 뭐에 쓰는가 하면 바로 코딩 튜닝에 사용한다.
ILDASM이란 녀석으로 튜닝하는데 이건 나중에 다시 이야기 해보자.

이전 글을 보시려면 http://www.wolfpack.pe.kr/category/Developer/.NET

2007/04/04 18:39 2007/04/04 18:39

좀 늦은 감이 없지 않아 많지만 객체를 이야기하기전에 배열과 구조체를 지나침으로써 객체를 정확히 이해하는데 어려움을 주고 말았다.
따라서 뒤늦게나마 배열/구조체를 이야기해보도록 하자.

배열이란 여러개의 변수를 포함하는 데이터 구조이다.

1차원, 다차원, 가변 배열등 3가지의 인간이 생각할 수 있는 배열이 있는데 다시말하자면 아파트라고 생각하면 이해가 좀 쉬울려나?

이런 상상을 좀 해보자. 1층짜리 아파트가 있다고 가정하고 (하긴 누가 이렇게 짖겠냐만은...) 101호~105호까지 5개의 방이 있고 여기에는 각각 "김씨","박씨","이씨","최씨","민씨" 이렇게 5가구가 살고있다고 치자.

이제 "김씨"가 사는집을 어떻게 표현할 수 있을까?
1. 101호
2. 첫번째집
3. 김씨네집

이렇게 표현할 수 있을것이다. 이것을 데이터로 그대로 옮기면 다음과 같은 형태가 된다.

using System;

class Test {   public static void Main() {     string[] a = new string[]{"kim","park","lee","choi","min" };     //다음은 모두 같은 뜻이다.     //string[] a = {"kim","park","lee","choi","min"};     //string[] a; a= new string[]{"kim","park","lee","choi","min"};     //string[] a = new string[5];  a=new string[]{"kim","park","lee","choi","min"};         // 이렇게는 에러난다.     //string[] a = new string[5];  a={"kim","park","lee","choi","min"};     Console.WriteLine (a[0]);   } }


위의 예제를 실행해보면 알겠지만 이런식으로 배열에 넣고 한묶음씩 데이터를 처리할때는 편하게 할 수 있다.
단, 변수를 초기화하고나서 데이터를 나중에 넣을경우는 반드시 "new"를 써주도록 하자.

이제 다차원 배열을 생각해보자. 다차원 배열은 1차원배열이 여러게 있다는 것이다.
다시말해 아파트가 2층, 3층으로 올라 갔다고 생각하자.
1층에는 "김","박","이","최","민"이 살고 2층에는 "류","원","홍","왕","고"씨가 산다고하면 이것을 두개의 변수에 나눠서 하면 당연히 1차원 배열에서와 같이 2번 써주면 되지만 이거 영~ 불편하다. 따라서, 한변수에 때려넣고 1층 1호, 2층 3호와 같은 식으로 "지칭"하면 더 간단하게 코딩할 수 있을것이다.
다음의 예제를 보자
using System;

class Test {   public static void Main() {     string[,] a = {{"kim","park","lee","choi","min" },{"ru","won","hong","wang","ko"}};     Console.WriteLine (a[1,1]);   } }


"won"씨 아저씨가 "네!!"라고 응답하는가? ^^?

이제 가변배열이다. 가변배열은 위와 같이 2층에 5개의 아파트를 만든게 아니라 한층에는 평수를 좀 크게해서 1층에는 5개인데 2층에는 2개와 같이 각층의 아파트 갯수가 다를때 사용하는 방법 되겠다.
왜? 이렇게 사용하나? 그냥 크게 잡아서 2*5로 10개의 방을 만들어 놓으면 알아서 넣고 가져가면 되는데 말이다. 내 생각에는 아마도 "초기 컴퓨터의 용량문제와 깊은 관계가 있지 않을까 생각된다."
아무튼 한번 해보자. 물론 이것도 1차 배열의 응용일 뿐이다.

using System;

class Test {   public static void Main() {     string[][] a = {      new string[]{"kim","park","lee","choi","min" },      new string[]{"ru","won","hong"}     };     Console.WriteLine (a[0][3]);   } }


실행 해본다고 다는 아니고 이게 이해가 안되면 구조체를 이야기 할 수 없으니 이해가 안되면 1차원 배열부터 차근차근 다시 해보면서 오도록 하자.

이제 구조체다. 구조체는 배열보다 상위의 개념이다. 그리고 객체로 가는 중간단계이다. 왜?
배열에서 시작된 데이터의 집합을 좀더 직관적으로 명세화 하면서 만들어졌고 구조체에 "행위"다시말해 기능을 정의해놓은것이 객체이기 때문이다.

* 객체 = 스팩정의서(제원) + 기능정의서
* 구조체 = 스팩정의서(제원)
* 배열 = 데이터 집합

이제 예를 들어보면 다음과 같은 정보가 있다고 치자.

- 위치 : 동경 37.1, 북경 23.1

뭐 이런 데이터시트에 입력하고 빼고하는등의 일을 한다고 하면 어떻게 하겠는가? 배열로해결할 수 도 있겠지만 좀더 효율적인 방법을 사용할 필요가 있다. 그래서 대두된 것이 구조체(Struct)이다.
using System;

class Test {   public struct a{     public int x,y;     public a(int p, int q){       x = p;       y = q;     }   }   public static void Main(){         a A = new a(10,10);     Console.WriteLine ("X:{0},Y:{1}",A.x,A.y);         /*     //이렇게해도 마찬가지 결과     a A;     A.x = 10;     A.y = 20;     Console.WriteLine ("X:{0},Y:{1}",A.x,A.y);     */   } }



여기까지해서 객체의 전단계인 배열, 구조체까지 알아보았다.
여기에 하나더 보너스! 배열에 들어간 데이터를 모두 뽑아야 한다면 얼마나 노가다인가?
이럴때 쓰라고 있는 신의 선물이 있으니 바로 foreach문이다.

using System;

class Test {   public static void Main() {     string[,] a = new string[2,2]{{"kim","park"},{"ru","won",}};     foreach (string i in a){         Console.WriteLine (i);     }   } }


2007/03/21 17:59 2007/03/21 17:59

지난번에 "객체를 이제좀 알것같다.(클래스 편)"에서 클래스라는 넘을 한번 쯤 내가 이해하는 수준에서 뒤집어봤다.
뭐 나름대로 정리해본 결과 "객체란 속성과 기능을 정의한 정의서이다."라고 정의내려버렸다.
거기에 한걸음 더 나아가 클래스안에 있는 녀석들과 대화할 수 있는 인터페이스까지 소스상에서 만들어봤는데 "왜 그래야 하는가?"에 대한 물음에 대답하라면 "모든 클래스가 public으로 구현된다면 대규모 개발에서는 반드시 충돌이 일어날거다"라는 궁색한 변명밖에 할 수 없고 그것이 정답이라고 할 수도 없다.
객체지향 프로그래밍이란 하나의 표준이다. 따라서 생산성과 표준화란 미명하에 자유로운 프로그래밍 스타일을 해치는 말을 하고 싶지 않고 간단한 예로 PHP란 언어를 보면 객체지향이든 절차지향이든 원하는 스타일대로 프로그래밍하고픈 대로 하면 되는 언어는 이것이 정답이니까 이것으로 꼭 해야돼!라고 하는 것 자체가 언어의 특성을 죽이는 결과만 낳을 뿐이기에 더욱 더 그러하다.

오늘 하고 싶은 이야기는 객체의 인터페이스에서 더 나아가 객체 전체를 인터페이스 하는 방법인 상속에 대해 쓰려한다.
상속이라고 하니 굉장히 딱딱한 용어가 되어버리는데 이런 예를 들면 어떨까?

흔히 게시판이라고하는 사용자 저작 툴 다시말해 큰 의미의 객체에서 그 기능을 보면 쓰기, 읽기, 수정, 삭제, 그리고 리스팅 이렇게 5가지의 큰 기능이 있고 그중 하나인 쓰기만 하더라도 텍스트 입력, 이미지 링크걸기, 파일 업로드, DB저장 등의 기능이 세분화 되며 다시 텍스트 입력을 보더라도 HTML 코드 입력, 색깔지정, 크기 지정 등등의 세부 기능이 또 따로 존재한다.

여기에서 프로그래밍에서 변치않은 명제 "Division & Conquer"를 대입해보자.

쪼게고 쪼게서 쪼겔때가 없는 나머지 하나를 공략해 구현한다는 취지에서 보면 우리는 제일먼저 텍스트입력기능을 하는 클래스부터 개발해야 할 것이다. 그리고 HTML입력 클래스를 개발할 것이고 이미지 업로딩 기능을 하는 클래스를 개발하고 등등등 세부 클래스를 만들것이다.
그렇다면 이제 문제 이것을 어떻게 합칠 것인가라는 문제에 도달한다.
차에 비교한다면 타이어와 브레이크, 조향장치, 엑셀, 엔진등의 부품을 사다놓고 이를 조립하는 과정이랄까?

다시말해 "상속은 조립이다"

이를 코드로 예제로 들면 다음과 같다.

using System;

class Test {   public static void Main() {     //b클래스를 초기화한다.     b b = new b();     //b클래스에 없는 abc인터페이스를 설정한다.     b.abc = "Hello";     //b클래스에 없는 "mthod_a"를 호출하자.     Console.WriteLine (b.mthod_a());   } }

public class a{     private string aa = "1234";     public string abc{           get { return aa; }           set { aa = value; }     }     public string mthod_a(){         return aa;     } }

public class b:a{    public string bb = "bbbb";    public string mthod_b(){       return bb;    } }


예제를 보면 "b"클래스는 "a"클래스를 상속받았다. 이를 통해 무엇을 할 수 있는가?
Main()을 보면 "b"클래스를 초기화하여 메모리로 올렸음에도 a에 있는 인터페이스와 메소드를 작동시킬수 있는 것이다.

이것만 이해한다면 객체지향프로그래밍의 중요한 특징 2가지를 모두 이해한것이다.
나머지는 언어의 특성이므로 다음부터는 C#을 기준으로 이야기해보자.

2007/03/14 16:36 2007/03/14 16:36

개발업무를 한지가 8년이 넘어간다. OOP 프로그래밍이 내 주변에서 떠돈것이 8년쯤되나 보다.
그러나 이제서야 객체를 이해하게 되었다.

객체의 본질은 무엇인가? 그것에 대한 질문의 답을 이제야 얻은 것 되겠다.

공식으로 따지면 이따위 모양되겠다.

"객체 = 속성 + 할수있는것"

이것을 설명하며 각종 서적과 강의에서는 전화기가 어떻고 차가 어떻고 하며 떠든것이다.
다시말해
"객체는 그 객체를 설명하는 속성과 그 객체가 할 수 있는 것"을 정의한것 되겠다.

실제코딩으로 보면 이런 현태가 되는거다.

public class a{
    string aa = "1234";
    public string mthod(){
        return aa;
    }
}


아~ 얼마나 심플한가?
이것을 이해하는데 몇년을 걸렸다니 너무나 애석하기만 하다. 하긴 출발점이 잘못된 탓도 없지 않아 있으리라.

이제 이것을 사용해보자 b란 클래스에서 a란놈을 불러서 mthod라는 행동을 유발해보자.

using System;
class Test {
  public static void Main() {
    a al = new a();
    string r = al.mthod();
    Console.WriteLine (r);
  }
}
public class a{
    string aa = "1234";
    public string mthod(){
        return aa;
    }
}
}


그리고 속성을 건드려보자.
물론 건드릴 속성이 private속성의 aa라는 변수라면 인터페이스를 만들어줘야 한다.
using System;
class Test {
  public static void Main() {
    a ar = new a();
    ar.AA="abcdef";
    Console.WriteLine ("인터페이스결과:"+ar.mthod());
  }
}
public class a{
    private string aa;
    
    public string AA{
      get{
          return aa;
      } 
      set{
          aa = value;
      } 
    } 

    public string mthod(){         return aa;     } }


private가 아닌 public이라면 그냥 바로 설정하면 된다.
using System;
class Test {
  public static void Main() {
    a ar = new a();
    ar.aa = "12345";
    Console.WriteLine ("그냥박기:"+ar.mthod());
  }
}
public class a{
    public string aa;
    public string mthod(){
        return aa;
    }
}


갑자기 필받아서 이렇게 두서없이 쓰긴했지만... 하고 싶은 이야기는 바로 클래스는 데이터의 집합체로 봐야 한다는 결론을 내렸다. 이렇게 데이터의 집합체로 놓고 설계를 해보면 다음과 같이 할 수 있을것이다.

냉장고라는 녀석이 하는일을 클래스화 시켜 보면 이렇게 정의할 수도 있을것이다.
class 냉장고{
        절전기능 = "Y";
        색깔 = "파란";
        높이 = "2m";
        폭 = " 50cm";
        깊이 = "40cm";
        실내온도 = "20c";
        public void 냉각(온도){
           실내온도 = 온도;
        }
}


이런것은 많이 봤을터이고 업무로 한번 해보자. 은행원이 수납, 인출받는 업무만 한다고 가정하고
class 은행원{
        성별 = "여";
        유니폼색 = "하늘색";
        public void 인출(금액){
              계좌 -= 금액;
        }
        public void 수납(금액){
              계좌 += 금액;
        }
}

2007/03/07 10:57 2007/03/07 10:57