본문 바로가기
Programming/Tips(C++,C#)

Factory Pattern

by 곰네Zip 2022. 7. 18.

* 이 글은 C#기준으로 작성하였습니다.

 

Factory Pattern. 

 같은 인터페이스를 가지는 여러 클래스들을 생성하려고하면.. 이 패턴을 쓰는것이 좋았다. (개인취향임..)

예를 들어, 비슷한 역할을 하는 클래스들이 여러개가 필요하다고 하면.. 이걸 매번 각각의 위치에서 생성하는 것도 하나의 방법이 되겠지만, 이걸 어느 한곳에서만 생성하게 해준다면? 그리고, 해당 클래스들을 사용하는 입장에서는 어느 클래스를 사용해도 동일한 코드를 사용할 수 있다면?

 예를 들어, window client프로그램인데, Database에 접속하는 경우를 생각해보자..

 MySQL, MS-SQL에 접속한 클래스들을 만든다고 하면?

public class MSSQLHandler{
   public void Connect(...){
     connection codes...
   }
}

public class MySQLHandler{
   public void Connect(...){
      connection codes..
   }
}

...

public void Main(int argc, char** argv){
  if( dbType == MSSQL){
    MSSQLHandler msHandler = new MSSQLHandler();
    msHandler.connect(...);
  }
  else if( dbType == MySQL){
    MySQLHandler myHandler = new MySQLHandler();  
    myHandler.connect(...);
  }
}

 이렇게 처리하면 된다..

 근데.. 호출하는 쪽에서 내가 어느 타입으로 접속했는지 매번 기억하고있다가, 그에 맞게 if-else처리로 쿼리도 날리고 해야할것이다. 그래야 저 Handler들을 다 기억하고 있지...

 이걸 막기위해서는 다음과 같이 처리하면 된다..

public class SQLHandler{
   private DbType type;
   public SQLHandler(DbType type){
      this.type = type;
   }
   
   public void Connect(...){
     if( type == MSSQL){
       //mssql connection string
     }
     else if(type == MySQL){
       //mysql connection string
     }
   }
}

 이러면 되기는 한다.. 되긴 하지.

 근데 지원할 DB가 추가되었다면? if-else가 하나 추가된다.

 그리고 메소드를 읽기가 엄청 난해해진다. 길어지거든..

 

그럼 아까의 MySQLHandler, MSSQLHandler형태로 각각 구현하고, 호출하는쪽에서는 한번 Handler생성해두고 기억할 필요가 없게 만든다면 어떨까?

 -> 인터페이스로 뽑아보자

public interface IDBHandler{
   void Connect(...);
}

public class MSSQLHandler : IDBHandler{
   public void Connect(...){
     connection codes...
   }
}

public class MySQLHandler : IDBHandler{
   public void Connect(...){
      connection codes..
   }
}

public void Main(int argc, char** argv){
  IDBHandler handler = (dbtype == MSSQL) ? new MSSQLHandler() : new MySQLHandler();
  handler.connect(...);
}

  위와 같이 쓰면.. 한번 핸들러를 생성해두면, 그냥 IDBHandler인터페이스의 메소드를 호출하면 끝이다.

다만, 생성할때마다.. 저 dbtype을 비교하여 추가하도록 해주면 된다.

 근데.. 저 handler를 생성하는 코드가 여러곳이라면? 

 DB하나 추가되면.. 그 여러곳을 한땀한땀 장인의 손길로 고쳐줘야한다.

 귀찮다!!!

 그러니 대신 만들어주는 애를 하나 만들자.

public class DBHandlerFactory{
   public IDBHandler CreateHandler(DBType type){
      IDBHandler result = null;
      if( type == MSSQL){
         result = new MSSQLHandler();
      }
      else if(type == MySQL){
         result = new MySQLHandler();
      }
      return result;
   }
}

public static void Main(int argc, char** argv){
   DBHandlerFactory factory = new DBHandlerFactory();
   IDBHandler handler = factory.CreateHandler(dbType);
}

 이렇게 해주면, 호출하는 쪽에서는 DBHandlerFactory와 dbType만 알고있으면 여러 타입의 DB Handler를 만들 수 있다. 확장하기 좋다.

 DBHandler의 메소드를 static으로 만들거나, Singleton을 적용하면 더 깔끔해진다. 

 Factory Pattern을 적용하려면, 비슷한 클래스들에서 공통되는 인터페이스를 뽑아내는 것과 그 인터페이스를 통해 실 객체를 생성해주는 역할을 관리해주는 클래스가 필요하다. 

 활용하기는 개인별로 알아서. :)

반응형

댓글