본문 바로가기

개인공부/소프트웨어 개발 패턴

(생성패턴) Abstract Factory 추상 팩토리 패턴

추상 클래스를 사용하여 같은 패밀리의 클래스들을 하위자식으로 가져 자식 클래스들이 추상 부모 클래스의

함수를 정의하도록 강제한다.

 

왜 사용하는가?

 

인터페이스와 비슷하지만 살짝 다르다.

인터페이스는 필드와 생성자를 갖지 못하지만 

추상 클래스는 필드와 생성자를 갖을 수 있다.

 

또한 추상 클래스를 부여받은 자식은 추상 메서드만 구현하면 된다.

 

 

 

하지만 여기선 패턴 공부이기때문에 거의 비슷한 인터페이스로 구현해 보았다.

아래 가짜 프로그램은 데이터베이스와 소켓구현방식을 추상팩토리로 구현해본 코드이다.

 

 

추상 클래스 두개

    public interface IConnection
    {
        string QueryHost();
    }

 

    public interface IHost
    {
    }

 

추상 팩토리 클래스 ( 또한 추상 클래스 두개를 포함하고 있다)

 

    public interface IConnectionFactory
    {
        IHost CreateHost();
        IConnection CreateConnection(IHost host);
    }

 

 

 

데이터베이스 부분 추상 클래스 두개 (서버, 클라이언트)

(서버)

 public class DatabaseHost : IHost
 {
     private readonly string _connectionString;

     public string EmployeeTable;

     public DatabaseHost(string location)
     {
         _connectionString = location;
         EmployeeTable = $"SELECT * FROM {_connectionString};\n\n" +
                 "**************************\n" +
                 "* ID * Name * Department *\n" +
                 "**************************\n" +
                 "* 1  * Joe  * Marketing  *\n" +
                 "* 2  * Mary * Accounting *\n" +
                 "**************************\n";

     }
 }

 

(클라이언트)

    public class DatabaseConnection : IConnection
    {
        private readonly DatabaseHost _host;

        public DatabaseConnection(DatabaseHost host)
        {
            _host = host;
        }

        public string QueryHost()
        {
            return _host.EmployeeTable;
        }
    }

 

커넥션 추상팩토리의 구현자 ( 데이터베이스 )

 

    public class DatabaseConnectionFactory : IConnectionFactory
    {
        public IConnection CreateConnection(IHost host)
        {
            return new DatabaseConnection(host as DatabaseHost);
        }

        public IHost CreateHost()
        {
            return new DatabaseHost("CompanyDatabase.EmployeeTable");
        }
    }

 

 

소켓 부분 추상 클래스 두개 (서버, 클라이언트)

(서버)

    public class SocketHost : IHost
    {
        private readonly string _ipAddress;

        public SocketHost(string location)
        {
            _ipAddress = location;
        }

        public string GetConnectionStatus()
        {
            return $"Socket connection to {_ipAddress} is open\n";
        }
    }

 

(클라이언트)

    public class SocketConnection : IConnection
    {
        private readonly SocketHost _host;

        public SocketConnection(SocketHost host)
        {
            _host = host;
        }

        public string QueryHost()
        {
            return _host.GetConnectionStatus();
        }
    }

 

커넥션 팩토리 구현자 (소켓부분)

    public class SocketConnectionFactory : IConnectionFactory
    {
        public IConnection CreateConnection(IHost host)
        {
            return new SocketConnection(host as SocketHost);
        }

        public IHost CreateHost()
        {
            return new SocketHost("180.157.114.17");
        }
    }

 

 

메인파트

 

    class Program
    {
        // this method doesn't need to know anything about
        // the concrete type of factory, connection, or host
        // that it uses
        static void CreateAndQueryConnection(IConnectionFactory factory)
        {
            var host = factory.CreateHost();
            var connection = factory.CreateConnection(host);
            Console.WriteLine(connection.QueryHost());
        }

        static void Main(string[] args)
        {
            CreateAndQueryConnection(new Database.DatabaseConnectionFactory());
            CreateAndQueryConnection(new Socket.SocketConnectionFactory());
        }
    }

 

 

결과값

 

SELECT * FROM CompanyDatabase.EmployeeTable;

**************************
* ID * Name * Department *
**************************
* 1  * Joe  * Marketing  *
* 2  * Mary * Accounting *
**************************

Socket connection to 180.157.114.17 is open