폼과 상호작용하여 사용자의 요청에 따라 도서 개체를 관리하고 도서 추가와 삭제, 변경을 수행할 때 구독자에게 이벤트를 게시하는 등의 프로그램의 주요한 제어 기능을 담당하는 BookManager 클래스를 정의합시다.
class BookManager {
도서 개체의 일련 번호는 순차적으로 부여합니다. 일련 번호를 부여하기 위한 멤버를 선언하세요.
int next_bs_no = 1;
도서 일련 번호를 키로 하고 도서 개체를 값으로 하는 사전 개체를 생성합니다.
Dictionary<int, BookStory> bdic = new Dictionary<int, BookStory>();
도서 추가/삭제 이벤트를 멤버로 선언합니다.
internal event AddEventHandler OnAddBS = null;
도서 변경 이벤트를 멤버로 선언합니다.
internal event ModifyEventHandler OnModifyBS = null;
도서 관리자 개체는 응용 프로그램에 유일하지 않으면 폼마다 서로 다른 도서 관리자 개체와 상호 작용하게 구현하는 실수를 범할 수 있습니다. 하나의 도서 관리자 개체를 사용해야 폼들 사이에 상호 작용에 버그가 발생할 확률을 줄일 수 있으니 단일체 패턴을 적용하기로 합시다.
#region 단일체 표현
도서 관리자 단일체를 위한 정적 멤버를 선언합니다.
static BookManager bm = null;
도서 관리자 단일체를 가져오기 할 수 있는 속성을 제공합니다.
internal static BookManager BM { get { return bm; } }
정적 생성자에서 단일체를 생성합니다.
static BookManager() { bm = new BookManager(); }
생성자의 접근 지정을 private으로 설정하여 다른 클래스에서 도서 관리자 개체를 생성할 수 없게 합니다.
private BookManager() { } #endregion
도서를 추가하는 기능을 제공합니다.
internal bool AddBook(string title, string description, int no, string imagename,DateTime dt) {
먼저 같은 일련 번호를 갖는 도서 개체가 있는지 확인합니다. 만약 있다면 false를 반환합니다.
if (bdic.ContainsKey(no)) { return false; }
도서 개체를 생성하여 사전 개체에 추가합니다.
bdic[no] = new BookStory(no, title, description, imagename, dt);
다음에 부여할 도서 일련 번호를 1 증가합니다.
next_bs_no++;
도서 추가/삭제 이벤트 구독자가 있으면 이벤트를 게시합니다.
if (OnAddBS != null) { OnAddBS(this,new AddEventArgs(bdic[no],true)); }
성공을 반환합니다.
return true; }
도서 일련 번호 목록을 구하는 메서드를 제공합시다.
internal List<int> GetNoColloction() {
도서 일련 번호를 보관할 컬렉션 개체를 생성합니다.
List<int> list = new List<int>();
사전 개체의 키 목록의 일련 번호를 컬렉션에 추가합니다.
foreach (int no in bdic.Keys) { list.Add(no); }
컬렉션을 반환합니다.
return list; }
일련 번호로 도서 검색 기능을 제공합시다.
internal BookStory FindBook(int no) {
사전 개체에 일련 번호가 없으면 예외를 던집니다. 개발 단계의 버그를 빠르게 발견하기 위해서도 예외 처리를 사용할 수 있습니다.
if (bdic.ContainsKey(no)==false) { throw new ApplicationException("없는 일련 번호로 도서 검색 요청"); }
사전 개체의 인덱스 연산으로 도서 개체를 반환합니다.
return bdic[no]; }
다음에 부여할 일련 번호를 확인하는 메서드를 제공합시다.
internal int NextBSNo() { return next_bs_no; }
일련 번호로 도서 삭제 기능을 제공합시다.
internal void RemoveBS(int no) {
사전 개체에 존재하지 않으면 예외를 던집니다.
if (bdic.ContainsKey(no)==false) { throw new ApplicationException("없는 번호 왜 삭제하래. 잘 사용해라."); }
사전 개체에서 도서 개체를 구하여 사전 개체에서 제거합니다.
BookStory bs = bdic[no]; bdic.Remove(no);
도서 추가/삭제 이벤트 구독자가 있으면 이벤트를 게시합니다.
if (OnAddBS != null) { OnAddBS(this, new AddEventArgs(bs, false)); } }
도서 목록을 구하는 메서드를 제공합시다.
internal List<BookStory> GetBSCollection() {
도서 개체를 보관할 컬렉션 개체를 생성합니다.
List<BookStory> bsl = new List<BookStory>();
사전 개체의 값 목록의 도서 개체를 컬렉션에 보관한 후 컬렉션 개체를 반환합니다.
foreach(BookStory bs in bdic.Values) { bsl.Add(bs); } return bsl; }
도서 정보를 변경하는 메서드를 제공합시다.
internal void ModifyBS(int no, string description, string imagename, DateTime dt) {
사전 개체에 일련 번호가 있는지 확인합니다.
if (bdic.ContainsKey(no)) {
있을 때 사전 개체에서 일련 번호로 도서 개체를 찾습니다.
BookStory bs = bdic[no];
입력 인자로 도서 개체의 속성을 설정합니다.
bs.Description = description; bs.ImageName = imagename; bs.DT = dt;
도서 변경 이벤트 구독자가 있으면 이벤트를 게시합니다.
if (OnModifyBS != null) { OnModifyBS(this, new ModifyEventArgs(bs)); } } } }
▷ BookManager.cs
using System; using System.Collections.Generic; namespace MyReadingStory { class BookManager { int next_bs_no = 1; Dictionary<int, BookStory> bdic = new Dictionary<int, BookStory>(); /// <summary> /// 도서 추가 이벤트 /// </summary> internal event AddEventHandler OnAddBS = null; /// <summary> /// 도서 변경 이벤트 /// </summary> internal event ModifyEventHandler OnModifyBS = null; #region 단일체 표현 static BookManager bm = null; /// <summary> /// 도서 관리자 단일체 - 가져오기 /// </summary> internal static BookManager BM { get { return bm; } } static BookManager() { bm = new BookManager(); } private BookManager() { } #endregion internal bool AddBook(string title, string description, int no, string imagename,DateTime dt) { if (bdic.ContainsKey(no)) { return false; } bdic[no] = new BookStory(no, title, description, imagename, dt); next_bs_no++; if (OnAddBS != null) { OnAddBS(this,new AddEventArgs(bdic[no],true)); } return true; } internal List<int> GetNoColloction() { List<int> list = new List<int>(); foreach (int no in bdic.Keys) { list.Add(no); } return list; } internal BookStory FindBook(int no) { if (bdic.ContainsKey(no)==false) { throw new ApplicationException("없는 일련 번호로 도서 검색 요청"); } return bdic[no]; } internal int NextBSNo() { return next_bs_no; } internal void RemoveBS(int no) { if (bdic.ContainsKey(no)==false) { throw new ApplicationException("없는 일련 번호로 도서 삭제 요청"); } BookStory bs = bdic[no]; bdic.Remove(no); if (OnAddBS != null) { OnAddBS(this, new AddEventArgs(bs, false)); } } internal List<BookStory> GetBSCollection() { List<BookStory> bsl = new List<BookStory>(); foreach(BookStory bs in bdic.Values) { bsl.Add(bs); } return bsl; } internal void ModifyBS(int no, string description, string imagename, DateTime dt) { if (bdic.ContainsKey(no)) { BookStory bs = bdic[no]; bs.Description = description; bs.ImageName = imagename; bs.DT = dt; if (OnModifyBS != null) { OnModifyBS(this, new ModifyEventArgs(bs)); } } } } }