[Design pattern - 실무편] Excel 빌더 패턴 만들기
안녕하세요. 명월입니다.
이 글은 Builder 패턴을 실무에서 어떻게 사용하는 지 소개하는 글입니다.
Builder 패턴의 경우는 보통 Entity 객체를 자동으로 만들어 주는 개념의 패턴입니다.
예를 들면 데이터 베이스에서 데이터를 검색해서 나오는 데이터를 List<Entity>의 형식으로 만드는 것도 빌드 패턴입니다.
사실 데이터 베이스의 데이터를 class 객체화 시키는 게 좋은 예이기는 하지만 너무 간단한 예제이기 때문에 저는 Excel의 데이터를 Entity로 내보내는 예제를 만들겠습니다.
먼저 Excel의 데이터를 읽어 드리는 NPOI 라이브러리를 사용하는데 NPOI의 설명은 다음 링크를 참조해 주세요.
[C#] NPOI를 이용하여 Excel를 읽어드리고 다시 출력하기 - https://nowonbun.tistory.com/400?category=507116
다음의 엑셀 데이터를 읽어서 Entity라는 클래스에 List로 만들 생각입니다.
먼저 데이터를 담을 Entity 클래스를 만듭니다.
class Entity
{
// Excel의 1열
public int Index { get; set; }
// Excel의 2열
public String Data1 { get; set; }
// Excel의 3열
public String Data2 { get; set; }
}
그리고 Excel로 부터 데이터를 가져와서 위 Entity클래스로 변환 시킬 빌더를 만듭니다.
class ExcelBuilder
{
private IWorkbook workbook;
public ExcelBuilder(String path)
{
this.workbook = GetWorkbook(path);
}
// 빌드할 시트 인덱스를 받는다.
public List<Entity> Build(int sheetIndex)
{
List<Entity> ret = null;
var sheet = this.workbook.GetSheetAt(sheetIndex);
// 첫번째 행은 타이틀이니 생략한다.
int rowindex = 1;
while (true)
{
// 두번째 행부터 데이터를 가져온다.
var row = sheet.GetRow(rowindex++);
// 행이 Null이 나오면 데이터 끝으로 기준한다.
if (row == null)
{
break;
}
// 행의 첫번째 열이 Null이면 데이터 끝으로 기준한다.
if(row.GetCell(0) == null)
{
break;
}
// Flyweight 패턴으로 데이터가 하나도 없으면 null를 내보낸다.
if (ret == null)
{
ret = new List<Entity>();
}
// 데이터를 읽어서 Entity 클래스를 생성한다.
var entity = new Entity();
entity.Index = (int)row.GetCell(0).NumericCellValue;
entity.Data1 = row.GetCell(1)?.StringCellValue;
entity.Data2 = row.GetCell(2)?.StringCellValue;
// 리스트에 넣는다.
ret.Add(entity);
}
return ret;
}
// 엑셀 파일을 읽어 드리는 함수
public IWorkbook GetWorkbook(string filename)
{
using (var stream = new FileStream(filename, FileMode.Open, FileAccess.Read))
{
return new XSSFWorkbook(stream);
}
}
}
다음은 실행 부분입니다.
class Program
{
static void Main(string[] args)
{
// 엑셀을 읽어드린다.
var builder = new ExcelBuilder(System.Environment.CurrentDirectory + "\\TestData.xlsx");
// Entity를 만든다.
var list = builder.Build(0);
// null이 아니면
if(list != null)
{
// 결과 출력
// 1 Test1-1 Test2-1
// 2 Test1 - 2 Test2 - 2
// 3 Test1 - 3 Test2 - 3
// 4 Test1 - 4 Test2 - 4
// 5 Test1 - 5 Test2 - 5
foreach (var item in list)
{
Console.WriteLine("{0} {1} {2}", item.Index, item.Data1, item.Data2);
}
}
Console.WriteLine("Press any key...");
Console.ReadKey();
}
}
소스를 보면 엄청 간단한 것처럼 보입니다. 그러나 실제 업무를 가보면 패턴 적용을 안하고 실행 흐름대로 Excel을 읽어드리는 부분을 만드는 분이 꽤 있습니다.
실제로 그런 소스를 보면 엄청 복잡합니다. 사실 그게 소스가 복잡한게 아니라 패턴 적용이 안되서 엄청 지저분 해 보이는 것입니다.
이렇게 패턴 적용을 하면 소스가 정말 단순해 보이고 명확하게 보입니다.
정말 잘 만든 소스는 정말 프로그램이 쉬워 보이도록 만든 소스라고 저는 믿고 있습니다.
여기까지 Excel builder 패턴에 대한 설명이었습니다.
궁금한 점이나 잘못된 점이 있으면 댓글 부탁드립니다.