본문 바로가기

모두보기

[C#] Delegates 대리자와 Events 이벤트 중 선택하기 Delegates 대리자와 Events 이벤트 중 선택하기 C# 의 언어 기능 중 Delegates 대리자와 Events 이벤트는 매우 유사합니다. 심지어 이벤트는 대리자 기능에 기반을 두고 있죠. 대리자와 이벤트 둘 다 런타임에 구현 코드가 바인딩되는 시나리오로 구성되어 있습니다. 또 두 기능 모두 Invoke() 메서드로 호출됩니다. 이러한 유사성으로 인해 언제 대리자를 또는 이벤트를 사용할지 결정하기가 어려울 수 있습니다. 대리자와 이벤트 중 어떤 언어 기능을 사용할지 결정할 때 가장 중요하게 고려해야 할 사항은 구독자가 있어야 하는지의 여부입니다. 대리자의 경우 구독자가 없다면 메서드를 호출하는 의미가 없으므로, 구독자가 필수적으로 필요합니다. 만약 대리자를 메서드의 매개 변수로 넘겨주는데, 대리..
[C#] Events 이벤트 Events 이벤트 먼저 용어부터 정리해보도록 합시다. 프로그래밍 세계에서 이벤트는 하나의 개념이 아니라 하나의 시스템입니다. 이벤트는 사용자의 클릭과 같은 행동에 대해 프로그램이 순차적으로 반응을 일으킬 수 있도록 고안된 시스템입니다. 디자인 세계에서는 이를 인터렉션이라 하죠. 옛날 옛적에 프로그램이 순차적으로 실행되는 코드에 불과하던 어셈블리어 시절, 이벤트라는 시스템은 불필요했습니다. 왜냐하면 사용자는 프로그램에게 명령어를 지정해 실행하는 행동만 취할 수 있었으니까요. 프로그램이 처리해야 할 이벤트는 '실행'에 따른 '결과'를 검은 배경에 하얀 글자로만 출력하면 되었습니다. 하지만 그래픽 인터페이스의 등장으로 사용자는 마우스로 다양한 버튼을 클릭할 수 있게 됩니다. 즉 ..
[C#] Covariance 공변성 및 Contravariance 반공변성 공변성 및 반공변성 마이크로소프트의 공식문서에서 공변성과 반공변성에 대한 개념을 소개하고는 있지만, 저는 이해하기가 너무 어려웠습니다. 저에게는 글 구성이 너무 난해하고 배경 설명이 너무 부족했습니다. 그래서 저와 같은 어려움을 겪는 개발자를 위해 제 나름대로 이해한 내용을 정리하여 기록해봅니다. 모두에게 유익한 글이 되기를... 상속 관계에 있는 클래스는 서로 형변환이 가능합니다. 다만 형변환을 하게 되면 정의된 범위와 구현된 범위가 달라지게 됩니다. 그래서 객체 간에 형변환을 하게 되면 예상치 못한 예외가 발생하곤 합니다. 특히 공변성과 반공변성이라는 개념은 이러한 형변환으로 파생되는 예외와 관련된 개념입니다. C# 언어가 발전하면서 .NET 내부적으로 제네릭 타입과 대리자 기능을 활발하게 사용되었습..
[C#] Delegates 대리자 Delegate (대리자)를 왜 사용해야 하는지, 그리고 어떤 상황에 사용되는지 살펴보자. 설계 목적 마이크로소프트 공식 문서에 따르면 Delegate (대리자) 기능은 아래와 같은 목적으로 설계되었습니다. Late Binding 동적 바인딩을 지원하는 언어 구문을 만들어, 개발자가 여러 다양한 소프트웨어 설계 문제에 동적 바인딩을 적용하여 해결할 수 있도록 설계 C 언어의 메서드 포인터와 같이, 메서드를 호출할 수 있는 방법이 필요해서 지정된 메서드를 호출할 수 있는 대리자 와 여러 메서드 호출을 연결할 수 있는 대리자를 프레임워크에 구현 C/C++ 언어와 달리 C# 언어는 모든 구문에서 Type-Safe(형식 안전성)를 지원하므로, 대리자도 Type-Safe(형식 안전성)를 지원 동적 바인딩 기능과 ..
[C#] 비동기 프로그래밍 비동기 프로그래밍 비동기 프로그래밍은 중앙처리장치(CPU)를 효율적으로 사용하기 위한 기술이다. 중앙처리장치는 매 초마다 정말 많은 작업을 요청받고 처리한다. 데이터를 읽거나 쓰거나, 네트워크 통신을 주거나 받거나, 화면 픽셀을 계산하거나 모두 중앙처리장치의 허가와 지도가 필요하다. 이렇게 바쁜 중앙처리장치에게 현재 입출력 작업이 완료되길 기다리게 하는건 정말 비효율적이다. 그래서 개발자는 중앙처리장치가 비효율적으로 낭비되지 않도록 비동기 프로그래밍 기술을 사용하여, 중앙처리장치가 입출력을 기다리는 대신 다른 업무를 처리하도록 하고 입출력이 완료되었다는 메세지를 받은 뒤에 기존 작업을 다시 시작하도록 프로그래밍한다. 등장 배경 기본적으로 프로그램은 코드 순서에 따라 순차적으로 실행된다. 그래서 코드 중간..
[SOLID] Dependency Inversion 원칙 목차 Single Responsibility 원칙 Open/Closed 원칙 Liskov Substitution 원칙 Interface Segregation 원칙 Dependency Inversion 원칙 Dependency Inversion (의존관계 역전) 원칙 상위 모듈과 하위 모듈은 추상적인 약속을 기반으로 소통해야 한다. 자세한 구현은 추상적인 개념에 기반해야 한다. Dependency Inversion (의존관계 역전) 원칙은 객체지향 설계의 핵심인 모듈 간 의존관계 해소를 강조하는 원칙이다. 모듈 간의 의존 관계가 낮아져야 모듈 세부사항을 변경하더라도, 전체 코드에 미치는 영향을 최소화하고 적은 양의 코드로 최대의 효과를 누릴 수 있다. 구체적으로 이야기하자면, 상위 모듈이 하위 모듈의 함수..
[SOLID] Interface Segregation 원칙 목차 Single Responsibility 원칙 Open/Closed 원칙 Liskov Substitution 원칙 Interface Segregation 원칙 Dependency Inversion 원칙 Interface Segregation (인터페이스 분리) 원칙 인터페이스를 구현하는 클래스는 필요한 함수만 구현할 수 있도록 설계하자. 원칙에 따라 인터페이스는 최소한의 크기로 설계해야 한다. 그래야 클래스가 필요한 부분만 구현할 수 있다. 예제 청바지 가게에서 아래와 같이 상품을 구현한다고 하자. public interface IProduct { int ID { get; set; } double Weight { get; set; } int Stock { get; set; } int Inseam { ..
[SOLID] Liskov Substitution 원칙 목차 Single Responsibility 원칙 Open/Closed 원칙 Liskov Substitution 원칙 Interface Segregation 원칙 Dependency Inversion 원칙 Liskov Substitution (리스코프 치환) 원칙 자식 클래스를 부모 클래스처럼 사용할 수 있도록 설계해야 한다. Liskov Substitution 법칙는 상속과 관련된 규칙이다. 자식 클래스가 만약 부모 클래스에서 기대하는 기능과 달리 동작한다면, 같은 부모 클래스를 상속하더라도 자식 클래스마다 기대하는 결과가 달라지는 어처구니없는 사태가 발생한다. 따라서 자식 클래스는 사용자가 부모 클래스로부터 기대하는 정도에서 너무 멀어지지 않도록 구현해야 한다. 예제 아래 예제 코드는 Circle-e..