'Functional World' 카테고리의 글 목록 (2 Page) :: iopeni - Think of C#

요즈음 들어 이 DI Pattern에 상당한 관심을 갖게 되었습니다.


이 포스트의 내용은 상당히 주관적인 내용들이기 때문에 제가 잘못 공부 하여 적는 내용들이 있을 지도 모르겠습니다.


잘못된 부분이 있다면 아낌없는 지적을..... 부탁 드립니다.


일단 Dependency Injection 이란게 무엇인지 알아야 겠죠..


전통적인(???) 이라고 해야 할지 모르겠으나, 오래된 프로그래 개발 방법들을 보면 제어를 담당하고 있는 핵심 Core는 해당 프로그램의 모든 Type을 알고 있어야 했습니다.


예를 들자면 아주 오래된 이야기 입니다만 Windows 이전이 DOS 라는 OS를 사용할 당시엔 화면에 무엇인가 출력 하기 위하여 각종 그래픽 카드들의 드라이버를 어플리케이션이 구현 하여, 프로그램에 탑재 해야 했습니다. 더불어 프린터로 출력 하기 위해서는 어플리케이션에서 각종 프린터 드라이버를 탑재 해야 했으며, 음악을 플레이 하기 위해서 각종 사운드 카드 드라이버를 프로그램에 탑재 하여야 했습니다.


그런데 Windows 라는 OS가 발표 되면서 사실 프로그램 개발자는 각종 디바이스 드라이버를 신경 쓰지 않아도 되는 시대가 도래 했죠. 


모든 디바이스 드라이버는 윈도우가 탑재 하였고 그게 어떤 디바이스 드라이버든지 응용 프로그램에서는 신경 쓰지 않고 화면에 출력 또는 프로그램에 출력, 음악 연주를 하는 세상이 Windows를 통해서 도래 하였습니다.


이런 시대가 도래 함으로서 개발자는 상당히 많은 부분의 부담을 덜어도 되었는데 하나의 출력물을 출력 하기 위하여 HP의 프린터인지 Epson의 프린터인지 LG 프린터인지 신경 쓰지 않아도 되는 정말 편리한 세상이 된 것이죠. 


이런 형태를 하나의 Dependency Injection(의존성 주입) 패턴이라고 봐도 무방 합니다.


즉 어플리케이션은 OS에 어떤 프린터가 설치 되어 있는지 몰라도 되는 상황이 된 것이죠 결국 출력 하기 위해서는 Print 라는 명령문만 날려주면 출력이 이루어지는 세상 말이죠. 


이 DI Pattern 을 구현하고 있는 프레임웍들이 상당히 많은데 사실 이런 용어를 제일 먼저 이야기 한 분은 이 시대의 개발 선구자 중 한명인 마틴 파울러 라는 분입니다.


마틴 파울러가 Inverse of Controls(IoC) 제어 역행화 방법론을 제일 먼저 소개 하였으며, 이것이 많은 개발자들에게 영감을 주어 정말 많은 프레임웍이 세상에 등장 하게 되었죠. 


많은 사람들에게 DI 와 IoC가 같은 레벨의 방법론으로 인지 되고 있으나 사실 DI에 비하여 IoC가 조금 더 추상적인 내용 입니다.


DI 패턴을 공부 하기 위하여, 우리가 제일 먼저 알고 있어야 하는 것은 OOP의 Interface 입니다.


눈치 빠른 분들께선 뭐 당연한 이야기네 라고 말씀 하시겠지만. Interface라는 것이 어떤 타입이든 관계 없이 해당 타입의 메소드 만 존재 한다면 타입 캐스팅이 필요 없이 사용할 수 있는 메커니즘 때문 이라는건 누구나 주지 하고 있는 사실 일 것입니다.


뭐 이쯤해서 서론은 마치기로 하고 몇가지 패턴들에 대해서 이야기 해 보도록 하겠습니다.


GoF의 디자인 패턴 중 Factory 패턴을 보게 되면 이 패턴이 이야기 하고 있는 것은 여러개의 동일한 행위를 하는 여러 타입의 객체를 중앙 집중화 할 수 있는 방법입니다.


회사의 규모에 따라 하나의 회사에는 여러명의 사원이 존재 합니다.


여러명의 사원은 각기 다른 업무를 수행하게 되겠죠.. 영업, 개발, 연구, 경원지원 등등등..... 과 같이 말이죠.


만약 한명의 개인의 급여를 계산 하는 프로그램이 있다고 가정 한다면 급여를 계산 하는 메인 프로세서는 이 사람의 부서, 직책, 직위, 시간외 업무 수당, 실적, 보너스 .. 등등 많은 것들을 고려 하고 있어야 할 것입니다. 


급여 계산을 수행 하고자 하는 메인 프로그램이 모든 사원에게 기본급을 계산 하는 룰은 같다고 가정 하고 각각의 부서별로 다른 급여 계산을 하는 비지니스 모델이라고 한다면, Employee 라는 추상 클래스로서 기본급을 계산 하는 Type을 생성 하고 이 Employee 라는 클래스를 상속 받는 부서별 Class를 작성하여 비지니스 로직을 분리 하고 이 객체를 좀 더 쉽게 생성 중앙 집중화 할 수 있도록 하는 Factory Pattern 을 사용하게 될 것입니다.


컨트롤러의 입장에서 바라 본다면 이 패턴의 문제점은 다음과 같을 것입니다.

어찌 되었든 컨트롤러 입장에서 바라 볼 때, 컨트롤러는 급여 계산을 하기 위하여 어떤 부서가 있는지 명시적 타입을 알고 있어야 할 것입니다.


이것은 DI 패턴이라고 할 수 없죠. 그래서 제시된 방법론이 ServiceLocator 라는 패턴 입니다.


이 ServiceLocator의 핵심은 다음과 같은 코드 입니다.


public class ServiceLocator
{

    private IDictionary<string, object> registeredTypes = new Dictionary<string, object>();

    public void Register<T>(string ServiceName, T obj)
    { 
        registeredTypes.Add(ServiceName, obj);
    }

    public T Locate<T>(string ServiceName)
    {
        return (T)registeredTypes[ServiceName];
    }
}

이 코드를 보면 Dictionary의 Key를 string 타입으로 지정 한 것을 볼 수 있습니다. 즉 각각의 부서명을 이용하여 실제 Object를 취득 하게 됨을 알 수 있습니다.


결국 메인 컨트롤러는 명시적 타입을 알지 못해도 되는 효과를 얻기는 했으나.....


두번째 정말 커다란 문제가 있죠.


만약 회사가 발전하게 되고 회사의 부서가 점점 늘어 나게 될 경우 메인 컨트롤러는 각각의 부서를 Register 하기 위한 코드가 부담 스러워 지게 될 것입니다.


역시 이 또한 Factory 패턴과 별반 다를게 없어 보입니다.


이것을 개선 하기 위하여 작성된 IoC 컨테이너의 핵심 코드를 보도록 하겠습니다.



public class IoCContainer
{

    private IDictionary<Type, object> registeredTypes = new Dictionary<Type, object>();

    public void ADD<T>(T instance)
    { 
        registeredTypes.Add(typeof(T), instance);
    }

    public T GetInstance<T>()
    {
        return (T)registeredTypes[typeof(T)];
    }
}

ServiceLocator 패턴의 핵심 코드와 별반 다르지 않습니다.


그런데 말이죠... 이 코드의 유용함이란.. 정말 이루 말 할 수 없겠네요.  이것으로 DI Container 의 기초 정리는 마무리....... 합니다.

Posted by 프로그래머란 카페인을 코드로 변환하는 기계다
,

객체 소거에 대한 단상....


얼마 전 아는 분이 몇가지 기술 적 자문을 구해 오셔서 그분 회사의 코드를 보던 중 질문 하신 범위 밖의 코드가 아주 심각한 문제가 있음을 발견 했습니다. 보고도 이야기 하지 않았습니다만..... 이야기 한다고 해서 그분이 이해 하시기엔 상당한 에로 사항이 있을꺼라는 ..... 제가 나쁜 놈이겠죠?


엔더스 헤일스버그라는 이 시대의 용자 께서는 .Net 을 설계 하시며, 절대 어플리케이션이 죽어서는 안된다 라는 명제를 가지고 정말 많은 고민을 하시었고(정말 고민을 했는지는 저도 모릅니다. 그냥 추측일 뿐입니다.)  생성된 객체가 소거 되었을 때, 누군가 소거된 객체를 호출 할 경우 어플리케이션의 종료를 막을 수 없고, 이 문제를 해결 하기 위하여, 가베지 컬렉터를 사용하여, 1세대, 2세대등...  사용자가 소거를 하여도 즉시 소거 되지 않고 가베지 컬렉터가 정말 사용하지 않는 객체를 소거 할 수 있도록 하는 시스템을 설계 하셨습니다.


아시는 분의 회사 코드를 보면 다음과 같은 황당한 코드가 담겨 있습니다.


private LIst<object> = new List<Object>();


public void funcion()

{

list.Clear();

list.ADD(new userControl);


//Todo....

}


그리고 화면에서 function을 호출 합니다.


결국 메소드가 한번 호출 될 때 마다 List를 비우고 다시 객체를 생성하여, 리스트에 담아 두게 되는데, 담겨 있는 객체를 소거 하는 문장은 어디에서도 찾아 볼 수 없습니다.결국 만든 유저 컨트롤 또 만들고, 또 만들고, 또 만들고........


엔더스 헤일스버그라는 이 시대의 용자가 설계한 마인드로 볼 때 결국 위와 같은 코드로 생성된  UserControl은 프로그램이 종료 될 때 까지 절대 소거 되지 않습니다. 


즉 Memory Leak 이 발생 한 거죠. 


만약 이 유저 컨트롤이 정말 큰 데이타를 취급 하게 된다면.... 이 프로그램이 메모리 부족 오류를 던지며, "나 일 못하겠다... 써글..." 이라고 이야기 하는 것은 시간 문제 입니다.


하나의 프로세스당 제한된 스레드 갯수... 하나의 스레드당 제한된 메모리 량을 생각 해 보면..... 사용 컴퓨터의 용량에 따라 어느 정도 가변적 이겠으나, 아주 위험한 코드죠 위와 같은 코드는.....


그래서 컬렉션에 있는 객체를 어떻게 소거 하여야 할까? 라는 문제를 생각해 보면 상당히 많은 방법들이 존재 합니다.


아주 무식한 방법으로 컬렉션에 담겨 있는 Controls를 Foreach로 순환 하며, 명시적 타입 캐스팅을 통한 타입 캐스팅 이후 각 타입이 가지고 있는 Dispose()를 호출 할 수도 있으나, 만약 저 List에 담기는 타입이 늘어 나면 늘어 날 수록 이 방법은 절대적 부담으로 작용 합니다. 


리스트에 담겨 있는 타입을 타입 캐스팅 해서 그 타입이 소거 대상 타입이라면 소거 하라는 메소드로 이관 하고 그 이관된 각 객체가 정말 이 시점에서 소거 하여야 하는 가를 검증 하는 잡이 발생 하게 되면... 이건 정말... 가관 입니다.


욕 나오는 코드를 작성 하게 되죠... 아마도 많은 초급 개발자 분들 께서는 이렇게 난해한 코드를 작성 하리라 생각 합니다.


그래서 살짝 힌트 아닌 힌트를 정리 합니다.


컬렉션에는 아주 유용한 메소드가 하나 있습니다.


ofType 메소드가 바로 그것이죠... 


이거에 확장 메소르를 하나 연결 하면 아주 쉬운 정리가 이루어 집니다. 다음 처럼 말이죠


//확장 메소드.

public static void ForEach<TItem>(this IEnumerable<TItem> sequence, Action<TItem> action)

        {

            // ToDo... 유효한 제거 인지에 해당하는 검증 작업 수행

                  검증하자....

// ---------------------------------------


            foreach(var item in sequence)

            {

                action(item);

            }

        }


// 컨트롤 클래스에서의 사용 이후 리스트 삭제 시점..

collection.OfType<IDisposable>().ForEach(ex => ex.Dispose());

collection.Clear();



짧은 코드로 원하는 잡을 수행 할 수 있다는 ..... ^^ 유용한 코드 입니다.





'Functional World > C#' 카테고리의 다른 글

라운드 트립 서식...  (0) 2015.05.06
널 병합 연산자.....  (0) 2014.12.15
윈도우 8.1 에서의 장치 독립적 코드 작성을 위한 DPI 설정 방법  (0) 2014.06.22
Form.ActiveForm  (0) 2013.11.07
바이트 배열 취득  (0) 2013.10.01
Posted by 프로그래머란 카페인을 코드로 변환하는 기계다
,

얼마 전 Canon 카메라를 이용하여, 좀 특수한 작업을 하는 알바를 하나 진행 하여야 했다.


업체에서 제공해준 캐논 카메라 SDK는 구버전을 제공해 주면서 최신 카메라를 지원 해 달라는 요구 사항이 있었다. 뭐 어쩔 수 없이 캐논 사이트로 직행 최신 SDK를 구하려 하였으나.


아시아권 개발자에게는 제공하지 않으며.......... (캐논 일본꺼 아니었던가?) 정히 구해야 하면 딜러를 통해 구하라는 메일을 받았다.


난감하지 않을 수 없었다. 그러나 이런 일에 절망할 내가 아니었다... 틀림없이 누군가 나 처럼 고생 했을 꺼고 그럼 누군가는 공유 해 놓았을 꺼야.. 라는 막연한 희망으로 구글링을 진행 했고... 그랬다.. 누군가 나 처럼 고생하다가 공유를 한게 아닌... NuGet을 이용한 다운로드 방법을 미국 사는 애가 정리해 놓은 글을 발견 했다.


지금 까지 그냥 쉽게 구할 수 있는 외부 라이브러리들을 쓸데없이 찾아 삼만리 하고 다닌 내가 부끄러웠다... 쉐뜨....


암튼 정리 하자면...






이렇게 쉽게 검색이 되고 그냥 Install만 누르면 참조 까지 알아서 자동으로 해주는 친절 함이.... 정말 폭풍 감동이 몰려 왔다.


내가 발견한 EDSDK를 NuGet으로 찾는 방법을 기술한 친구는 




콘솔을 이용한 방법을 정리 해 놓았더랬다.


뭐 어찌 되었든 나는 내가 원하는 라이브러리를 얻었으니 아 NuGet 좋은거다.. 라고 생각 하고 있던 즈음..


친한 동생 하나가 프리즘 라이브러리를 NuGet으로 취득 하려고 하니 신버전만 보이고 구버전은 안 보여서 곤란 하다는 제보를 해 주었다.


이거 정말 방법이 없는 걸까?


물론 방법은 있다.


위 이미지 에서 처럼 NuGet Manager Console을 실행 하고 보면 PowerShell 이 실행 된다. 


사실 이걸 보면 살짝 당황 한다. 여기서 부터 뭘 해야 하지? 라고 말이다.


쫄지 말고 ...... PM> Get-Help NuGet 이라고 두들겨 보자.


그럼 이렇게 뜬다.




대충 읽어 보면 Get-Package는 현재 프로젝트에 설치 되어 있는 Package를 조회 하거나 -ListAvailable을 통해 NuGet에 등록 되어 있는 Package를 조회 해 볼 수 있다는 걸 알 수 있다.


물론 딱 봐도 보이겠지만. Install-Package 로 패키지 설치를 할 수 있다는 것도 말이다.


과감하게.... PM>Get-Help Install-Package 를 두들겨 보면 


(누르면 크게 보인다.)


옵션에 -version 이 보인다.


만약 prism4 을 설치 한다고 가정 하자.


PM> Get-Package -ListAvailable Prism

이라는 명령으로 프리즘 라이브러리 관련된 것들을 조회 할 수 있다.





이제 설치를 해 보자.


PM> Install-Package Prism -version 4.0.0




이렇게 설치가 되는 것을 확인 할 수 있다...


아 고마운 NuGet...........


Posted by 프로그래머란 카페인을 코드로 변환하는 기계다
,

Control 클래스는 Control의 위치와 크기를 지정하기 위해서 사용하는 Location 과 Size라는 두 개의 Property를 정의 하고 있습니다.


Location Property 는 Point Structure Type 으로 X 와 Y라는 두개의 int type field를 포함 합니다. 단위는 Pixel 입니다. Location Property 는 부모의 왼쪽 위 모서리로 부터 떨어진 상대적인 위치를 가리킵니다.


Size Property 는 width와 height라는 두개의 field를 포함하는 Size Structure Type 이며, Pixel단위로 컨트롤의 크기를 지정 합니다.


다들 아시겠지만 SizeF 구조체는 실수형 타입 입니다.


모든 윈도우 폼은 폼이 가지고 있는 모든 컨트롤을 표시 할 수 있어야 하며, 이것은 결국 장치 독립적 폼으로 디자인 되어야 한다는 것을 의미 합니다. 

즉 개발자가 가진 노트북에서는 모든 컨트롤을 다 표시 할 수 있으나 다른 모니터로 이동하게 되면 모든 내용이 다 표시 되지 않는 사태가 발생 될 수 있으며 이런 것을 방지 하기 위한 것 입니다. 결국 예전의 모든 해상도에 맞게 또는 모든 모니터 디바이스에 맞게 폼을 다시 디자인 했었을 수도 있었을 것입니다. 이런 일들 정말 힘들고 고된 일들이죠. 저에겐 아직도 장치 독립적 이라는 주제가 어렵게 느껴집니다. 결국 저는 초딩 때 산수 공부를 정말 안한것 같습니다.


프린터는 기본적으로 300 dpi(dot per inch : 인치 당 dot(점) 의 수), 600 dpi, 또는 1200 dpi 와 같은 장치 해상도가 있는 것 처럼 비디오 디스플레이에도 특정한 장치 해상도를 가지고 있습니다. 윈도우 7 까지는 기본 해상도로 96 dpi가 사용 되었으나 윈도우 8 부터는 기본 해상도로 120 dpi가 사용 되고 있습니다.


윈도우 8.1을 설치 하고 난뒤 모든 것들이 전부 크게 보여 참 당혹스러워 했던 기억이 있습니다.


제가 가진 노트북의 Display panel은 물리적으로 15.7 인치의 사이즈 이며 이 사이즈 안에 1920 * 1080 (pixel)으로 이루어 져 있습니다. 


다른 환경에서 같은 것을 경험한다는 것은 참 어려운 일인듯 합니다만 마이크로소프트는 다른 사용자가 각기 다른 디바이스들에서 같은 윈도우 화면을 경험하게 하고자 했던 것 같습니다.


윈도우 8.1에서 이 dpi를 설정 하는 방법을 알아 보도록 하죠.


우선 바탕화면에서 마우스 오른쪽 버튼을 클릭하여, 개인설정을 표시 합니다.




개인 설정이 표시 되면 좌측 하단의 디스플레이를 클릭 합니다.


다음 화면에서 우리는 dpi 설정을 할 수 있습니다.



작게 - 100%(S)                 : 96  dpi (pixel / dot per inch)

보통(M) - 125%(기본값)      : 120 dpi (pixel / dot per inch)

크게 - 150%(L)                 : 144 dpi (pixel / dot per inch)


사용자 지정 크기 조정 옵션을 선택 하면 좀 더 다양한 Scale 을 지정 할 수 있습니다.


Windows Form Program 은 Graphics 클래스의 DpiX 와 Dpi Property를 사용하여, 비디오 디스플레이를 포함한 모든 그래픽 출력 장치의 해상도를 얻을 수 있습니다.


Windows Forms의 기본 글꼴은 약 9 Point 입니다. (포인트는 1/72 인치를 나타내는 측정 단위 입니다.) 이 값은 Font 클래스의 SizeInPoints로 구할 수 있습니다. 


장치 독립적인 프로그래밍을 위한 가장 근본이 되는 기초 이론을 살펴 보았지만.. 역시 이건 너무 어렵네요... 그냥 이런게 있다는 것 정도만.... OTL.....


Microsoft 의 Visual Studio는 AutoScaleDimensions 와 AutoScaleMode Property 를 사용하여 장치 독립적인 기능을 지원하고 있습니다. 이 Property들은 ContainerControl Class에 정의 되어 있습니다.

이 클래스는 Control클래스를 상속 받았으며, Form 클래스는 ContainerControl  클래스를 상속 받습니다.


AutoScaleMode Property 는 AutoCaaleMode Enum Value를 받습니다. 이 열거형은 다음과 같이 정의 되어 있습니다.


public enum AutoScaleMode

    {

        None,

        Font,

        Dpi,

        Inherit

    }


만약 AutoScaleMode 속성을 AutoScaleMode.Font로 설정 한다면, Form 클래스는 폼의 Font 속성에서 지정한 크기 비율(Font 의 크기 비율은 Font.height에 비해 Font.width 는 대략적으로 1/2의 비율 크기를 갖습니다.)에 따라서 모든 크기를 AutoScaleDimresions속성에서 지정한 배율 크기로 조절할 것입니다. 만약 윈도우가 96 DPI의 작은 배율로 설정 되어 있다면, VisualStudio는 다음과 같은 두 문장을 자동으로 추가 할 것입니다.


this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);

this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;


만약 디스플레이 해상도를 참조 하여 폼을 디자인 하고 싶다면 다음과 같이 할 수 있습니다.


this.AutoScaleDimensions = new System.Drawing.SizeF(96, 96);

this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;


this.AutoScaleDimensions = new System.Drawing.SizeF(120, 120);

this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;


아무리 봐도 이건 참 어렵습니다.



'Functional World > C#' 카테고리의 다른 글

널 병합 연산자.....  (0) 2014.12.15
Collection Object Dispose() 쉽게 하기......  (0) 2014.11.12
Form.ActiveForm  (0) 2013.11.07
바이트 배열 취득  (0) 2013.10.01
boxing 에 대한 생각의 오류....  (0) 2013.09.30
Posted by 프로그래머란 카페인을 코드로 변환하는 기계다
,

살면서 언제나 처음 보는 용어를 이해하는데는 상당한 시간과 노력이 필요 한듯 합니다.


WPF는 선언형 기반의 프로그래밍 언어 입니다.


XAML이라는 선언형 프로그래밍 언어로 Object를 선언하고 컴파일러는 이 언어를 파싱하여 가지고 각각의 Object를 생성합니다.


XAML 코드를 하나 보도록 하죠.

<window x:class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" title="MainWindow" height="350" width="525">
    <grid>
        <button>
            OK
        </button>
    </grid>
</window>

위 XML코드를 보면 Window 와 Grid, Button이라는 2개의 컨트롤과 1개의 윈도우를 생성하고 있습니다. 


Winform 형태의 프로그래밍을 보면 Grid와 Button은 동일 선상에 놓여 있는 Object 입니다. 그리드 안에 표현하기 위하여 우리는 그리드의 Contorls 컬렉션에 Add 하는 것으로 종속 관계를 표현 할 수 있겠죠.


그런데 WPF는 아닙니다. 어떻게 보면 컨트롤 자체가 컬렉션 처럼 보이기도 합니다. 그냥 <Grid>라는 태그를 선언하고 </Grid> 안에 <Button/>을 등록하는 것으로 Grid에 포함된 버튼이 생성 됩니다. 이런 형태로 종속관계의 Tree가 그려지게 됩니다. WPF에서는 이런 관계가 논리적트리(LogicalTree), 비주얼트리(VisualTree)라는 것으로 생성 됩니다. 


WPF는 화면을 디자인 할 때 기본으로 종속관계가 도식화 되며 이로 인하여, 각각의 컨트롤간 의존성을 띄게 되기 때문에 의존객체(DependencyObject)라고 표현 되게 되는 것입니다. 


이렇게 의존성을 띄게 되는 컨트롤만이 있다면 이건 뭔가 좀 이상해 보일 수도 있습니다.


의존프로퍼티가 이런 의존객체를 토대로 만들어진 개념입니다. 각 객체가 기본 의존성을 띄게 된다면 각 부모 객체의 프로퍼티에 의존성을 두기 쉽게 된 이유 입니다. 


즉 하나의 객체가 다른 객체에 포함된 경우라면 상위 객체의 프로퍼티 값을 상속 받아 기본 값으로 셋팅 되도록 구성 되었다는 것입니다.


<window x:class="WpfApplication1.MainWindow" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
title="MainWindow" height="350" width="525" fontsize="44">
    <grid>
        <button>
            OK
        </button>
        <button>
           OK
        </button>
    </grid>
</window>

와 같이 윈도우 객체의 FontSize를 44와 같이 두게 된다면 그 안에 있는 그리드와 버튼의 폰트 사이즈가 44로 셋팅 되는 의존성을 갖게 된다는 것입니다.


이 의존성에는 커다란 규칙이 하나 존재 하는데


프로퍼티 값 기준 결정 이라는 것입니다.

  • 로컬 값 설정(Local Value)
  • 스타일 트리거(Style Triggers)
  • 템플릿 트리거(Template Triggers)
  • 스타일 세터(Style Setters)
  • 테마 스타일 트리거(Theme Style Triggers)
  • 테마 스타일 세터(Theme Style Setters)
  • 프로퍼티 값 상속(Property Value Inheritance)
  • 기본 값(Default Value)

등의 순서로 의존성을 띄게 됩니다.


일단 의존객체라는 것과 의존프로퍼티의 의미를 알았다는 것으로 이 포스트를 마무리 할까 합니다.


애덤 네이선은 이렇게 이야기 하고 있습니다.


"WPF가 선언형 프로그래밍 언어 일 수 있는 것은 바로 의존객체와 의존프로퍼티 때문에 가능한 일이다." 라고 말입니다.



Posted by 프로그래머란 카페인을 코드로 변환하는 기계다
,

저 개인적으로는 코딩을 하며, 정말 유용하게 사용하였던 것이 정의로 이동 이라는 기능입니다. 이게 없으면 정말 미쳐 버릴 것만 같았죠.


디렉토리 찾아서, 클래스 찾아서 이동 후 코드 쳐다 보며 폭풍 스크롤... 이건 정의로 이동이 라는 기능이 없을 때 였습니다.


어느 순간 정의로 이동이라는 기능이 추가 되었고 굳이 내가 찾지 않아도 바로 찾아서 이동해 주니 이 처럼 편한게 없었죠.


그런데 이제는 정의 피킹 이라는 것이 생겼습니다.


코드 수정 중 호출 되는 쪽의 코드를 보고 싶을 때 살짝궁 눌러주면 호출 되는 클래스 또는 메소드의 코드를 확인 할 수 있습니다.


만약 바라 볼 수 없는 외부 라이브러리 라면 overload infomation 정도를 화면에 인라인으로 표시 하여 주는 군요....


정의로 이동 보다.... 정의 피킹을 많이 사용하게 될 것 같습니다.


정의 피킹으로 코드 확인 하고 

정의로 이동으로 이동 하여 수정하고, 다시 참조로 원래 작업 하던 코드로 이동 후 수정...


이제 3박자가 딱딱 맞아 들어 가는 군요 코드를 수정하며 코드 찾아 다니는 노가다를 줄여주는.......


  



'Functional World > Visual Studio' 카테고리의 다른 글

Visual Studio Installer Project  (0) 2014.12.30
NuGet  (0) 2014.10.24
Visual Studio 2013 사용자 편의 기능 - 참조  (0) 2013.11.29
Visual Studio 2013 혁신~~ 그 이상????  (0) 2013.11.22
Node.js Tool for Visual Studio  (0) 2013.11.22
Posted by 프로그래머란 카페인을 코드로 변환하는 기계다
,

Visual Studio의 사용자 편의 기능 중 참조 기능에 대해서 알아 보도록 하겠습니다.


일단 참조 라고 하면 우리는 쉽게 그냥 레퍼런스 라고 생각 할 수 있겠죠...


네 맞습니다. 


어디선가 누군가가 나를 호출 하고 있다면 누가 호출 하고 있는지를 알려주는 기능 입니다.


살짝꿍 화면 캡쳐를 해 봅니다.




위에서 보시는 것 처럼 참조를 클릭 하면 

작은 박스가 하나 뜨면서 Form1.Designer.cs 파일의 43번째 라인에서 이벤트 체인으로 버튼 클릭 이벤트를 호출 하고 있는 것을 볼 수 있습니다.


물론 선택을 하면 바로 정의로 이동 하는 것을 볼 수 있습니다.


예전 MZ-Tools 와 같은 코딩 보조 도구에서 지원해 주던 기능이죠 Caller 를 파악 하고 어디서 호출 하는지 알고 바로 접근하여 코드를 수정하던 예전 일들이 이제는 Visual Studio에 포함 되었습니다.


사실 이 기능이 너무 편한건 저 같은 초보자들이나 그런 걸까요? 저는 머리속에서 돌릴 수 있는 코드량이 극히 작으므로 예전 MZ-Tools나 CodeRush 같은 플러그인에 많은 의존을 했었습니다.


여러분은 어떠세요? 좋지 않은가요?


Posted by 프로그래머란 카페인을 코드로 변환하는 기계다
,

싱글톤 패턴의 의미는 프로젝트 전역에 걸쳐 객체를 단 하나만 생성하겠다는 의미 입니다.


예전 모 프로젝트 진행 도중 어떤 선임 개발자가 이 Singleton 패턴을 남발 하여 아주 곤란한 상황에 직면했던 적이 있는 그런 모델이기는 하나 시기 적절 하게 사용하게 되면 정말 유용한 패턴 입니다.


일단 이 Singleton Pattern을 이해하기 위하여 이 패턴의 용도를 알아야 겠습니다.


싱글톤 패턴의 용도는 쉽게 이야기 한다면  "공유 데이터의 동기화"에 해당하는 문제를 풀어 나가는 방법 입니다.


다시 말하여. 

A와 B라는 객체가 동일한 temp라는 프로퍼티를 가지고 있다고 할 때, 둘의 데이타는 언제나 같은 값으로 동기화 되어야 한다면, A.temp가 변경 될 때 B.temp도 변경 하여야 하고 B.temp가 변경 될 때 A.temp도 변경 되어야 한다는 조건이 성립합니다.


이것은 프로그래밍을 할 때 피해야 하는 요소 중 한가지 순환 참조의 조건에 해당 합니다.


당연히 순환 참조가 성립 되면, 객체는 각각 객체가 가진 프로퍼티에 대입되는 값을 동기화 하기 위하여 무한 루프에 빠지게 될 것이며, 이것을 해결 하기 위하여 우리는 또 인다이렉션이라는 설계를 하게 되겠죠


역시 모든 소프트웨어 공학의 정답은 인다이렉션 입니다.


리팩토링을 설명 하면서 잠깐 데이터와 상태의 전달에 대하여 언급한 적이 있는데. 역시나 같은 문제를 놓고 고민 하게 되는 것입니다.


싱글톤 패턴의 또 다른 용도로 DB 컨넥션에 해당하는 예를 들 수 있습니다. DB는 하나의 컨넥션이 맺어질 때마다 메모리를 할당 하게 되고 하나의 어플리케이션이 다수의 컨넥션을 맺게 되면 하나의 PC는 더 많은 DB 컨넥션을 맺게 될겻이고, 이렇게 되면 대규모 사이트 일 수록 DB서버는 어마 어마한 부하를 받게 될 겁니다.


위와 같은 문제로 3 Tier를 구성 하겠지만, 2 Tier의 상황에서도 하나의 어플리케이션이 단 하나의 컨넥션만을 유지 할 수 있다면 DB쪽 부하를 상당히 줄여 줄 수 있을 것입니다. 물론 미들티어를 가지고 있는 3 Tier의 상황에서도 클라이언트가 컨넥션을 한개만 유지해 준다는 것은 미들티어의 부하를 줄여 주는 방법이기도 합니다. 이렇게 보든 저렇게 보든 부하를 줄이기 위하여 다수의 컨넥션이라는 문제를 방치하는 것은 상당히 위험해 보입니다.


이런 문제로 하나의 컨넥션을 유지하는 명시적인 방법으로 싱글톤 패턴을 활용 하기도 합니다.


물론 비지니스 성격에 따라 하나의 어플리케이션은 다수의 컨넥션을 요구 하기도 합니다. 이런 문제를 잘 파악하여, 싱글톤 패턴을 활용 할 수 있다면 비교적 좋은 성능을 가질 수 있을 것입니다. 어떻게 보면 정답 처럼 보이기도 합니다.


이 컨넥션 문제를 놓고 또 한가지 고민 해야 할 사항이 있습니다.


하나의 어플리케이션은 OS로 부터 메모리를 할당 받으면서 임계 영역이라는 것으로 메모리 보호를 받게 됩니다. DLL 제작과 같은 방법으로 Data Access Layer를 Singleton Pattern으로 구성한다고 하여도 이 임계 영역이라는 문제로 인하여 하나의 어플리케이션 과 다른 어플리케이션은 객체를 공유 할 수 없는 문제가 발생 합니다. 예전 이런 문제를 해결 하기 위하여 DCOM과 같은 기술들이 나온 것이기도 합니다.


이것의 의미는 아무리 DAL을 잘 구성 한다고 하여도 각각의 어플리케이션마다 컨넥션을 맺게 된다는 것이고 하나의 PC는 다수의 컨넥션을 맺게 됩니다. 이유는 간단 합니다. 메모리 보호 문제로 각각의 어플리케이션이 가지고 있는 메모리 어드레스를 두 어플리케이션이 공유 할 수 없기 때문입니다.


.Net 환경에서 이것을 좀 쉽게 피해 갈 수 있는 방법이 있습니다. Component Model을 활용하면 쉽게 해결 할 수 있습니다. DCOM의 확장판은 Component Model이기 때문입니다.


이쯤 적으면 어느정도 초보 단계를 벗어난 개발자분이시라면.... 아 Remoting 또는 WCF를 활용하면 되겠구나 하실 껍니다. 맞습니다. Remoting, WCF 등등이 답입니다.


참고 MSDN : http://msdn.microsoft.com/ko-kr/library/vstudio/72x4h507(v=vs.100).aspx


을 확인 하시면 Remoting 은 호환성을 유지하기 위하여 아직 사용되고 있으나, 새로운 개발에는 WCF를 사용할 것을 권장 하고 있습니다. 


싱글톤 패턴을 설명 하려고 하다가 너무 멀리 와 버렸네요.


이 처럼 객체를 하나만 사용하겠다는 것은 많은 것들을 이야기 합니다. 또 다른 관점으로는 메모리와 데이타를 어떻게 사용하느냐의 문제 이기 때문에 프로그래밍의 발전 역사와도 맞물려 돌아 가겠죠.


어플리케이션이 동작하는 상태를 만약 싱글톤 패턴으로 관리 하게 된다면 어떨 까요? 현 상황에서 어떤 로직으로 분기 해야 하는지 아니면 현 상황에서 어떤 화면을 나타내야 하는지 등에 해당하는 내용을 싱글톤 패턴으로 관리 하게 된다면 좀 쉽지 않을까요? 여기 저기서 상태를 체크 하는 .. 또는 정리 되지 않은 또는 여기 저기 산재 되어 있는 비지니스 프로세스 때문에 고민하는 우는 좀 줄일 수 있지 않을까요? 거의 완벽에 가까운 인다이렉션 설계로 종속성 관리를 완벽하게 하지 못한다면 말이죠...


다음과 같은 C#  코드로 싱글톤 패턴을 구현 할 수 있습니다. 차암 쉽죠잉~~~ ^^

class SingletonTest
    {
        static void Main(string[] args)
        {
            var singleton = Singleton.getObject();
            getObject.SaySomething();

            Console.ReadKey();
        }
    }

    public class Singleton
    {
        private static Singleton _SingleObject;

        private Singleton() { }

        public static Singleton getObject()
        {
            if (_SingleObject== null)
            {
                _SingleObject= new Singleton();
            }
            return _SingleObject;
        }

        public void SaySomething()
        {
            Console.WriteLine("Test Singleton");
        }
    }

여기서 OOP를 잘 이해 하지 못하는 분들을 위해 몇가지 부가 설명을 적습니다.


규칙

1. 싱글톤 오브젝트는 오로지 하나여야 하기 때문에 static으로 제한 합니다.

2. 인스턴스는 static에 접근 할 수 있으나 static은 인스턴스에 접근 할 수 없습니다.


위 두가지 규칙이 Singleton패턴의 모든 규칙이라고 할 수 있습니다. 그런데 한가지 좀 심하게 고민 해 봐야 할 문제가 있습니다. 우연히도 완벽하게 동일한 시스템 클럭에 완벽하게 동일하게 두개의 클라이언트가 동시에 싱글톤 객체를 생성하려고 한다면 어떻게 하여야 할까요? 한번 고민해 보시길 바랍니다.


Posted by 프로그래머란 카페인을 코드로 변환하는 기계다
,

Visual Studio 라는 개발 도구는 이전 부터 사용자의 편의성이 극대화 되어 있던 개발 도구 였습니다. 아마도 다른 개발 환경을 사용 하고 계신 분들이라면 어쩌면 Visual Studio를 부러워 할 지도 모르겠다는 생각을 합니다.


(뭐 저는 개인적으로 잠시 이클립스를 가지고 자바 프로젝트를 진행 한 적이 있는데... 도대체 어렵더군요 공부하기도 어렵고 사용하기도 어렵고... 물론 익숙해 지면 정말 편하고 좋은 개발 환경인건 알겠습니다. 그런데 전 비쥬얼 스튜디오에 익숙한 개발자여서 그런지 기능 파악을 할때도 비쥬얼 스튜디오에는 있는데 여기는 없네? 이랬던 것들이 상당 부분 있습니다. 수 많은 이클립스 확장이 있고 저는 자바 전문 개발자가 아니어서 제가 잘 알지 못 하므로 있는데도 모르고 사용 했을 수도 있으니 자바 개발자 분들 께서는 저의 무지 몽매 함으로 이클립스가 나쁘다고 평가 하는 것이다. 라는 말씀을 하신다면.. 겸허히 받아 들이겠습니다.)

....


시대의 변화에 따른 개발 환경의 변화도 다른 시각에서 조명 되어야 할 때 라는게 Visual Studio 2013 발표 기조 연설에서 잘 보여지고 있습니다.


기조 연설 링크 : http://events.visualstudio.com/kor/sessions/details?SessionProfile=3925&TrackProfile=2839


Visual Studio 2013을 보면 로그인이라는 항목이 보여지고 있죠!!!!


몇몇 분들의 Visual Studio 2013 평가를 보면 이 로그인이 존재 한다는 것으로 도대체 쓸데 없는 행위를 해 놓았다고 악평을 하시는 분들의 글도 볼 수 있습니다.


로그인을 하지 않으면 Visual Studio 2013의 시작 페이지에 있는 동영상 링크 걸려 있던 항목들도 확인 할 수 없고,

시작페이지에 표시되는 Microsoft의 소식도 확인 할 수 없죠.


이제는 개발자가 개발환경을 바라보는 시각이 달라져야 합니다.


클라우드의 개념으로 Any Time, Any Device를 통해 내 프로젝트에 접근하여 - 개발, 디버깅, 배포 할 수 있는 시대가  된 것이고 Visual Studio 2013을 통해 안정적 서비스를 제공 받을 수 있는 시대가 도래 한 것입니다.


Visual Studio 2013을 설치 한 후 개발자가 설정 해 놓은 개발 환경을 다른 PC에서 구축 하고자 할 때..(PC한대만으로 개발을 하는 분들도 많이 있겠지만. 복수의 PC에 개발 환경을 구축해 놓고 작업 하는 분들도 많이 있죠. 사실 저는 3대의 PC에 개발 환경을 구축해 놓고 사용합니다.) 


또 다른 PC에 개발 환경을 구축 하고 설정을 변경 하여 나만의 개발 환경을 만드는 일이 사실 귀찮은 일이기도 합니다. 


사실 로그인 하나만을 하는 것으로 클라우드에 저장된 나의 개발환경이 동기화 되어 귀찮은 작업을 하지 않아도 된다는 장점이 있습니다. 이것은 실시간으로 동기화 되고 적용됩니다.


사실 이런 것 만으로 로그인을 해야 한다? 라고 보면 정말 쓸데 없는 일 입니다. 이런 기능은 없어도 사용하는데, 크게 불편해서 없으면 못살겠다. 뭐 이 정도는 아니죠. 사실 그다지 특별한 것도 없고 메리트도 없습니다.


그런데 말이죠 형상 관리툴을 보면 우리가 대표적으로 많이 쓰고 있는 것이 3가지 정도 되겠죠... 


1. SVN

2. MIcrofsoft Team Foundation

3. Git


Visual Studio 2013을 보면 기본적으로 형상관리를 Team Foundation 과 Git으로 할 수 있습니다.


여기에 Git이 왜 포함 된걸까요? 


이유는 기조 연설을 통해서 아주 유명한 에릭 감마 씨가 나와서 Monaco를 설명 할 때 분명히 알 수 있습니다.


Monaco가 무엇인지 모르는 분들을 통해서 잠시 설명 하자면... 웹 기반의 Visual Studio 입니다. 계정을 보유 하고 있는 사용자들에 한하여, 프로젝트를 무료로 Git을 통해서 Visual Studio Web Server에 등록 하고 계정을 가지고 있는 팀원을 등록 - 허가된 사용자는 누구나 이 프로젝트에 웹을 통해서 접근 개발, 수정, 디버깅, 컴파일 할 수 있는 웹 기반의 Visual Studio 입니다.


기조 연설에서는 에릭 감마씨가 타블렛 PC를 가지고 크롬으로 접속하여 컴파일 하고 있네요. 사실 계정만 있다면 로컬에 비쥬얼 스튜디오를 설치 하지 않아도 된다는 뜻이 되겠죠.


뭐 물론 로컬에 비쥬얼 스튜디오를 설치해 놓는것이 여러가지 확장 기능이나. 개발 환경의 자유로운 변경을 통해 최적의 개발 환경에서 개발 을 할 수 있는 장점이 있지만... 어찌 되었든 이제는 Visual Studio 도 클라우드 기반에서 동작 합니다.


뭐 이런 환경이 복잡 다단한 현 세계에서 족쇠로 다가와.... 휴가 중 동남아 여행중인데 갑자기 회사에서 연락을 받고 휴가중 일을 할 수 밖에 없는 환경에 처 하기도 굉장히 쉬워진 여건 이긴 합니다.


휴가중 업무에 시달리지 않기 위해 인터넷이 안되는 여행지를 찾아 돌아 다녀야 할지도 모릅니다.



어찌 되었든 이제는 언제나.... 어디서나... 무엇을 가지고든 일을 할 수 있는 환경이 된겁니다. 브라보~~ 를 외칠 것인가... 아니면 나 죽었다를 외칠 것인가는 여러분의 판단에 맡겨야 겠지요... ^^




Posted by 프로그래머란 카페인을 코드로 변환하는 기계다
,

Node.js 가 드디어 Visual Studio 에서 좀 자유롭게 사용 될 수 있는 환경이 구축 발표 되었습니다.


- 소개 -

http://www.hanselman.com/blog/IntroducingNodejsToolsForVisualStudio.aspx


- 확장 설치 -

https://nodejstools.codeplex.com/


이벤트 기반의 대규모 사이트 구축 스크립트인 서블릿 노드를 드디어 자유롭게 사용할 수 있겠네요

Posted by 프로그래머란 카페인을 코드로 변환하는 기계다
,