260 likes | 755 Vues
디자인 패턴 - 생성. 발표 강 희기 – 한발 ( 한국개발자 ) 커뮤니티 활동 목표 객체 생성을 삽질 안 하는 객체지향적으로 구조화된 코드로 작성하자 . - Factory Method - Abstract Factory - Builder 특히 FactoryMethod 와 AbstractFactory 의 정확한 차이점을 이해하자. 디자인 패턴 - Factory Method. Factory Method( or Factory) Pattern 반복되는 객체 생성 문제에 대한 해법을 제시
E N D
디자인 패턴 - 생성 • 발표강 희기– 한발(한국개발자)커뮤니티 활동 • 목표객체 생성을 삽질 안 하는 객체지향적으로 구조화된 코드로 작성하자.- Factory Method- Abstract Factory- Builder특히 FactoryMethod와 AbstractFactory의 정확한 차이점을 이해하자.
디자인 패턴 - Factory Method • Factory Method( or Factory) Pattern반복되는 객체 생성 문제에 대한 해법을 제시 • 문제1클라이언트코드에 객체생성코드(new)가 산개되어 복잡성이 가중된다. • 문제2클라이언트가 모든 생성타입을 알아야 하므로 타입추가 수정 시 컴파일 필요.배포와 유지보수가 어렵다.
디자인 패턴 - Factory Method • StarCraft종족 유닛생산 예로 설명종족설명 링크 : http://ko.wikipedia.org/wiki/%EC%8A%A4%ED%83%80%ED%81%AC%EB%9E%98%ED%94%84%ED%8A%B8%EC%9D%98_%EC%A2%85%EC%A1%B1 - 유닛(제품)분류 지상유닛: 드론, 프로브,SCV, 저글링, 질럿, 마린…공중유닛: 무탈, 케리어, 베틀크루즈,…- 생산건물(공장) 분류 저그유닛생산공장: 해처리(지상,공중)프로토스유닛생산공장: 넥서스, 게이트웨이, 스타게이트(공중)테란유닛생산공장 : 커맨더센터, 베럭스, 팩토리, 스타포트(공중)
디자인 패턴 - Factory Method • 문제1의 예.드론drone = new 드론();drone.doWork();drone = new 드론();drone.doWork(); 프로브prove = new 프로브();prove.doWork();에스시브이scv = new 에스시브이();scv.doWork();등의 코드들이 프로그램 내에 산개되어 코드가 복잡
디자인 패턴 - Factory Method • 문제2의 예.저글링이라는 새로운 유닛이 추가되었을 때.저글링unit = new 저글링();unit.doWork();라는 코드를 클라이언트 코드에 추가하여 컴파일을 해줘야 하는 문제.해결책 >>객체생성을 하나의 클래스로 묶어버리자.
디자인 패턴 - Factory Method • 모든 유닛생성공장 클래스를 만들자.Class AllUnitFactory(유닛생성공장){ 유닛 Create(UnitTypeunitType){ if(unitType == 드론) return new 드론(); if(unitType == 프로브) return new 프로브(); … if(unitType == 저글링) return new 저글링(); }}이렇게만 해도 문제1,2가 다 해결된다.
디자인 패턴 - Factory Method • 지금까지 내용 다이어그램 도식화. UnitType은 최종단계의 유닛 유닛생성공장+유닛Create(UnitType type) 유닛 드론 프로브 에스씨브이 저글링 클라이언트 코드에서 사용하는 클래스
디자인 패턴 - Factory Method • 지금까지 내용 클라이언트 코드enumUnitType = {드론,프로브,에스씨브이,저글링,…};void main(){유닛생성공장 factory = new 유닛생성공장(); //지상유닛 생성유닛unit = factory.Create(드론); unit .doWork(); unit = factory.Create(드론); unit = factory.Create(프로브); unit = factory.Create(에스씨브이); … //공중유닛 생성 unit = factory.Create(무탈); }생성을 팩토리 하나로 모으니 종족별로생산로직이 다르다. >> 종족별 생산공장의 필요성.
디자인 패턴 - Factory Method 공장을 세분화 하고 나니 type에 각 종족의 최종유닛을 넘길 필요성이 없어진다.>> 타입추상화 필요 ( 지상유닛, 공중유닛)저그족지상유닛1,2,… 드론, 저글링, …공중유닛1,2.,… 무탈, 퀸,…프로토스족지상유닛 프로브,질럿,…공중유닛 커세어, 케리어,…테란족지상유닛 SCV,마린, …공중유닛 레이쓰, 베틀크루져,…
디자인 패턴 - Factory Method >> type은 유닛의 size가 와도 상관없다. 제품을 특징짓는 임의의 분류
디자인 패턴 - Factory Method • 정의.Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses. 객체생성의 인터페이스는 정의하지만 서브클래스가 어떤 클래스를 인스턴스화 하게 할지 결정하게 한다.factorMethod()는 서브클래스에세 임의의 클래스의 인스턴스화를 연기하게 한다. 예) 유닛공장unitFactoy = new 저그족생성공장();유닛groundUnit1= unitFactoy.Create(‘지상유닛’); • 유닛skyUnit1= unitFactoy.Create(‘공중유닛’); • 예) 유닛공장unitFactoy = new 저그족생성공장();지상유닛unit1 = unitFactoy.Create(‘지상유닛’); • 공중유닛unit2 = unitFactoy.Create(‘공중유닛’); • >> 유닛공장이라는 추상클래스의 Create를 호출하면 실제로 저그족 생성공장의 Create가 객체생성을 담당.
디자인 패턴 - Factory Method • 다이어그램. >> 특정 공장에서 생산되는 제품즉, 제품은 공장의 특징을 반영한다.장점>제품분류가 추가되면 구현제품클래스만 추가하고 생산하면 된다. 단점 > 추상성이 오직 하나인(제품) 구현객체를 생산. 제품분류가 상속에 포함되어 있지 않아 구현객체의 분류를 한눈에 알기 힘들다.
디자인 패턴 - Abstract Factory • 제품의 부분(분류)들을 묶어 어떤 기능을 해야 할 경우 >> 지상유닛, 공중유닛 각각 하나씩 만들어 하나의 묶음으로 이용해야 할 경우.>> 제품분류를 제품의 상속에 포함시킨다.이것도 일종의 추상화?
디자인 패턴 - Abstract Factory • 생산지가 아닌 제품분류을 기준으로 분류
디자인 패턴 - Abstract Factory • 분류별 생산공장의 경우 코드- UnitType이 지상,공중유닛(각각 공장의 함수로정의해도 상관없다.)//저그공장의 경우유닛Create(UnitTypeunitType){ if(unitType == 지상) return new 드론(); // 저그의지상유닛 if(unitType == 공중) return new 무탈(); …} //테란공장의 경우유닛Create(UnitTypeunitType){ if(unitType == 지상) return new 에스씨브이(); …}
디자인 패턴 – Abstract Factory • 팩토리메소드의 확장된 형태의 패턴 지상유닛 드론 저그생산공장 공중유닛 무탈 Create지상유닛() Create공중유닛() 장점 : 제품분류가 상속에 포함되어 명시적이다.제품의 분류를 추상성으로 이용 할 수있어 코드 이해가 쉽다.단점 : 제품의 분류 추가 시 추상클래스부터 구현클래스까지 한셋을정의해야한다.
디자인 패턴 - Abstract Factory • 생산과 관련된 현실세계의 예 -> 다이어그램으로 표현 해보자. (과제?)1. 자동차생산- 종류 : 소형, 중형, 대형- 생산 : 현대, 대우,…2. 문서생성- 종류 : 매출문서, 사내규율문서, 공지문서, 보안문서, … - 생산 : 서울지점, 대구지점, 대전지점, 부산지점, …
디자인 패턴 - Abstract Factory • 닷넷프레임웍에서의 사용 예
디자인 패턴 - Abstract Factory • 코드 샘플 public sealed classSqlClientFactory : DbProviderFactory{// Fieldspublic static readonlySqlClientFactory Instance; // Methodsstatic SqlClientFactory();private SqlClientFactory();public override DbCommandCreateCommand();public override DbCommandBuilderCreateCommandBuilder();public override DbConnectionCreateConnection();public override DbConnectionStringBuilderCreateConnectionStringBuilder();public override DbDataAdapterCreateDataAdapter();public override DbDataSourceEnumeratorCreateDataSourceEnumerator();public override DbParameterCreateParameter();public override CodeAccessPermissionCreatePermission(PermissionState state); // Propertiespublic override boolCanCreateDataSourceEnumerator { get; }} • // CreateCommand는 그냥 SqlCommand를 생성해서 리턴하기만 한다..public override DbCommandCreateCommand(){return new SqlCommand();}
디자인 패턴 - Abstract Factory • 코드 샘플 DbProviderFactorydbProviderFactory;DataTabletblFactoryClass = DbProviderFactories.GetFactoryClasses();ConnectionStringSettingsdbConnectionSettings; dbConnectionSettings = ConfigurationManager.ConnectionStrings[tblFactoryClass.Rows[iProvider][0].ToString()];dbProviderFactory = DbProviderFactories.GetFactory(tblFactoryClass.Rows[iProvider]); // 3번이 SqlServerDbCommanddbCommand = dbProviderFactory.CreateCommand();DbConnectiondbConnection = null; DbParameterdbParameter1 = dbProviderFactory.CreateParameter();dbParameter1.ParameterName = "@PAGE";dbParameter1.DbType = DbType.Int32;dbParameter1.Size = 4;dbParameter1.Value = NowPage;dbCommand.Parameters.Add(dbParameter1); DbParameterdbParameter2 = dbProviderFactory.CreateParameter();dbParameter2.ParameterName = "@PAGE_SIZE";dbParameter2.DbType = DbType.Int32;dbParameter2.Size = 4;dbParameter2.Value = PageSize; dbCommand.Parameters.Add(dbParameter2);dbCommand.CommandText = "BoardPagingSelect";dbCommand.CommandType = CommandType.StoredProcedure; //defaultDataTabletblResult = new DataTable();using (TransactionScopetransactionScope = new TransactionScope()) //default TransactionScope{ dbConnection= dbProviderFactory.CreateConnection();dbConnection.ConnectionString = dbConnectionSettings.ConnectionString;dbConnection.Open(); dbCommand.Connection= dbConnection;dbCommand.CommandType = CommandType.StoredProcedure;dbCommand.CommandText = "BoardPagingSelect";dbCommand.CommandTimeout = dbHelper.IntTimeout; if (dbHelper.IsPrepare)dbCommand.Prepare(); DbDataAdapterdbHelperAdapter = dbProviderFactory.CreateDataAdapter();dbHelperAdapter.SelectCommand = dbCommand;dbHelperAdapter.Fill(tblResult);if (dbConnection.State != ConnectionState.Closed)dbConnection.Close(); BoardDataList.DataSource= tblResult;BoardDataList.DataBind();}
디자인 패턴 - Builder • 부분들이 조합한 완제품을 만든다.(복잡한객체생성)Direct라는 중간클래스를 두어 생성과 표현을 분리 지상유닛 드론 저그생산공장 공중유닛 Create지상유닛 Create공중유닛 무탈 생산공장 GetResult(); //추상팩토리 패턴의 공장에 GetResult라는 메소드를 추가 하고 Direct라는 클래스를 두어 생성과 표현을 분리한다.
디자인 패턴 - Builder • 클래스 다이어그램 Builder가 완제품이 아닌 그냥 제품 하나라고 하면 Factory Method와 동일
디자인 패턴 - Builder • 순차 다이어그램