파이프라인 패턴
·
소프트웨어 공학
들어가기에 앞서... 해당 패턴은 동시성 프로그래밍에 기반한 디자인 패턴이기 때문에 동시성 프로그래밍을 지원하는 언어가 아닌 경우 이 글이 별로 도움이 되지 않을 것이다. 또한 해당 글은 Go언어만의 문법을 쓰기 때문에 동시성 프로그래밍을 지원한다 하더라도 다른 언어에서는 구현 방법이 다를 수 있다. 즉, 해당 글은 Go언어 사용자 중 동시성 프로그래밍에 대한 기본 개념(고루틴, 채널)에 대한 기본 지식이 있는 독자를 대상으로 한다. 파이프라인 패턴은 디자인 패턴 중 실행 패턴이다. 디자인 패턴 목록에 나열한 글에 없다고 의아해할 수 있다. 맞다. 해당 패턴은 전통적인 디자인 패턴('GoF의 디자인 패턴'에 포함된 패턴)은 아니다. 이는 해당 패턴이 일반화되지 않았다거나 바람직하지 않다는 것을 뜻하는 것..
DIP 원칙의 한계
·
소프트웨어 공학
들어가기에 앞서... 지난 글에서는 DIP 원칙이란 무엇인지, 또 DIP의 장점과 적용하는 방법에 대해서 설명했다. 해당 원칙대로 작성한 코드는 순환 참조 문제에 빠질 일이 없고 객체지향적으로써 바람직한 코드가 될 것이다. DIP 원칙 그 자체로써는 단점이 거의 없다.(아주 없지는 않다. 코드의 길이가 살짝 늘어난다. 물론 이러한 단점은 장점에 비하면 매우 사소하다.) 이 글의 제목이 '단점'이 아닌 '한계'라는 사실에 주목하라. 그렇다면 이 글에서 설명하고자 하는 한계는 무엇인가? 바로 DIP 원칙을 적용할 수 없는 경우이다. 상위 폴더에 인터페이스를 두기만 하면 DIP 원칙이 적용된다고 생각할 수 있고 또 어느 정도는 사실이지만, 이것이 불가능한 경우가 존재한다. 이 글에서는 DIP 원칙을 적용할 수..
Go 언어에서의 DIP
·
소프트웨어 공학
들어가기에 앞서... 해당 글은 독자가 Go 언어(혹은 C언어 계열)의 문법에 대한 기본 지식이 있다고 가정하고 설명하겠다. 객체지향적 설계에 관해 집중적으로 공부한 적이 있다면 'SOLID 원칙'이라는 용어는 들어봤을 것이다. SOLID 원칙은 로버트 마틴이 그의 저서 '클린 소프트웨어'에서 제창한 용어로 다섯 가지 객체지향 소프트웨어 디자인 원칙의 약자를 모은 것이다. 이번 글에서는 이 다섯 가지 원칙 중 마지막 원칙인 DIP(의존성 역전 원칙)에 대해 설명할 것이다. 해당 원칙은 이해하기가 어려운 대신, 이해만 한다면 (특히 Go언어에서)바로 적용하기 쉬운 유익한 원칙이다. 정의 상위 모듈은 하위 모듈에 의존해서는 안 된다. 상위 모듈과 하위 모듈 모두 추상화에 의존해야 한다. 추상화는 세부 사항에..
[Go with TDD] 테이블 주도 테스트
·
소프트웨어 공학
개요 이전에 '깔끔하게 go test의 테스트케이스를 짜는 법'이라는 글을 쓴 적이 있다. 오늘 설명할 테이블 주도 테스트는 해당 글의 내용을 정형화한 기법이다. 테이블 주도 테스트 테이블 주도 테스트(table-driven test)는 메소드에 대한 여러 개의 테스트 케이스를 하나의 테이블로 구성하는 테스트 기법이다. 테스트할 메소드 하나에는 여러 개의 테스트 케이스가 존재한다. 일반적으로 테스트를 작성하면 하나의 테스트 함수는 하나의 테스트 케이스를 실행한다. 이렇게 작성하는 것이 잘못된 것은 아니지만 호출할 메소드가 같기 때문에 코드의 중복이 생긴다. 테이블 주도 테스트는 하나의 테스트 함수에 테스트할 메소드의 테스트 케이스를 묶어 테이블로 만든 후 해당 테이블을 순회하며 테스트를 진행하는 구조이다..
[Design Go] 가교 패턴
·
소프트웨어 공학
들어가기에 앞서... 필자는 해당 패턴이 디자인 패턴에서 제일 중요하다고-적어도 Go언어에서는-생각한다. 만약 독자가 해당 시리즈를 정주행하고 있다면 한 번 쉬고 오기를 바란다. 아, 해당 패턴이 어렵다는 뜻은 아니니 걱정하지 않아도 된다. 해당 패턴에서는 도형을 그리는 예제를 이용할 것이다. 도형을 그리는 방식으로 Raster 방식과 Vector 방식을 들 수 있는데, Raster 방식은 점을 일일히 찍어서 표현하는 방식이고 Vector 방식은 그래프를 이용해 수학적 방식으로 표현하는 방식이다. 예제에서 구현할 도형은 원과 직사각형 두가지로 한정한다. 모든 경우의 수를 고려한다면 각 경우의 수를 담당하는 클래스를 만드는 방법을 떠올릴 수 있다. RasterRactangle, VectorRactangle..
[Design Go] 적응자 패턴
·
소프트웨어 공학
들어가기에 앞서... 이번 글 부터는 구조 패턴에 관해 설명할 것이다. 구조 패턴은 연관된 객체를 합성하는 방법에 관한 디자인 패턴이다. 생성패턴과는 다르게 구조패턴은 서로 연관성이 없는 경우가 많기 때문에 각 글마다 예시가 다를 것이다. 해당 예시는 외부에서 위치를 표현하는 Point 구조체와 글을 표현하는 TextView 인터페이스 및 클래스를 들여왔다고 가정한다. 그리고 우리는 도형을 표현하는 Shape 인터페이스를 작성했다. 우리가 원하는 작업은 위의 TextView를 Shape 처럼 이용하는 것이다. 즉, TextView 클래스를 Shape 인터페이스에 맞추는 것이다. //point.go package main import "fmt" type Point struct { X, Y int } fun..
[Design Go] 단일체 패턴(동시성 프로그래밍을 중심으로)
·
소프트웨어 공학
들어가기에 앞서... 드디어 마지막 생성 패턴이다. 예제는 지난 글과 동일하다. 이번 글은 동시성 프로그래밍의 내용을 포함하고 있기 때문에 해당 내용에 관해 알고 있으면 좋다. 패턴 단일체 패턴은 객체(Singleton)를 단 하나만 생성하도록 하는 패턴이다. 프로그램 내에서 Singleton 객체는 오직 하나이며 프로그램 실행 중 처음 접근할 때만 초기화가 이루어진다. 프로그램 어느 곳에서든지 Singleton 객체에 접근 가능하며 어느 곳에서 접근해도 같은 객체를 가리킨다. 즉, 전역 변수와 같은 기능을 한다. 장점 전역 변수의 상위 호환이다. 전역변수를 쓸 때에는 여러가지 부작용을 감수해야 한다. 단일체 패턴은 이런 전역변수의 부작용을 최소화한다. 이에 관해서는 아래의 장점들에 자세히 풀어놓았다. ..
[Design Go] 원형 패턴
·
소프트웨어 공학
들어가기에 앞서... 예제는 전과 마찬가지로 지난 글의 예제를 이용했다. 원형 패턴 원형 패턴은 미리 만들어진 객체(prototype)의 복사를 통해 새로운 객체를 생성하는 패턴이다. prototype 객체는 보통 팩토리 객체(factory) 내부의 인스턴스로 존재하며, factory 객체는 요청한 prototype 객체의 복사본을 반환한다. prototype 객체를 복사할 때에는 깊은 복사를 이용해야 한다. 장점 런타임 단계에서 새로운 객체의 생성자를 만들 수 있다. 이는 컴파일 단계에서 생성할 객체의 클래스를 정해야 하는 다른 생성 패턴에 비해 유연성이 보장된다. 클래스의 개수가 줄어든다. 다른 생성 패턴은 인터페이스를 만족하는 다양한 클래스들을 생성해야 하지만 원형 패턴은 하나의 클래스에 내부의 p..