ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 디자인 패턴 - 1
    Book/스프링 입문을 위한 자바 객체지향의 원리와 이해 2022. 1. 3. 23:03

    디자인 패턴을 왜 알아야할까? 디자인 패턴이라면 일종의 설계도 레시피이다. 프로그램을 작성하다 보면 비슷비슷 한 경우가 자주 발생하는데 이럴땐 이렇게 하라라는 레시피를 정리 해 둔 것이다.


    Adapter Pattern(어댑터 패턴)

     

    호출당하는 쪽의 메서드를 호출하는 쪽의 코드에 대응하도록 중간에 변환기를 통해 호출하는 패턴

    adapter == converter 변환기로 서로다른 두 인터페이스 사이에 통신이 가능하게 하는 것이다.

     

    //AdapterServiceA
    
    public class AdapterServiceA {
        ServiceA s1 = new ServiceA();
    
        void 메서드(){
            s1.메서드A();
        }
    }
    //AdapterServiceB
    
    public class AdapterServiceB {
        ServiceB s2 = new ServiceB();
    
        void 메서드(){
            s2.메서드B();
        }
    }
    //Client
    
    public class Client {
        public static void main(String[] args){
            AdapterServiceA a1 = new AdapterServiceA();
            AdapterServiceB a2 = new AdapterServiceB();
    
            a1.메서드();
            a2.메서드();
        }
    }

    각각 ServiceA, ServiceB의 변환기를 만들었다. Client class에서 변환기를 이용해 메서드()를 호출 하면 각각의 변환기에서 각 메서드를 실행시켜준다.

     

    따라서 =호출당하는 쪽의 메서드 {메서드A(), 메서드B()}를 호출 하는 쪽의 코드에 대응되도록 중간에 변환기{AdapterServiceA, AdapterServiceB}를 두어 호출하는 패턴이다.

     


    Proxy Pattern(프록시 패턴) => OCP(개방 폐쇄 원칙) + DIP(의존 역전 원칙)

     

    제어 흐름을 조정하기 위한 목적으로 중간에 대리자를 두는 패턴

    프록시의 뜻은 대리자라는 뜻이다. 대신해서 역할을 수행하는 것이다.

     

    프록시 패턴의 경우 실제 서비스 객체가 가진 메서드와 같은 이름의 메서드를 사용하는데 이때 인터페이스를 사용한다. 인터페이스를 사용하면 서비스 객체가 들어갈 자리에 대리자 객체를 대신 넣어서 클라이언트 쪽에서는 대리자인지 실제 서비스인지 모르게 된다.

     

    client가 대리자(proxy)를 이용한 호출 -> proxy(인터페이스 구현)는 호출에대한 흐름 제어(서비스 객체 만들고 메서드 실행), 반환결과는 그대로 전달(가감 X) - > client에게 전달

     

    => 결국 client는 대리자를 이용해서 호출을 하고 대리자는 실제 서비스의 객체를 만들어 메서드를 반환한다.

     

    //interface
    
    public interface IService{
    	String runSomething();
    }
    //실제 Service
    
    public class Service implements IService{
    	public String runSomething(){
        	return "blabla";
        }
    }
    //대리자 proxy
    
    public class Proxy implements IService{
    	IService service1;
        
        public String runSomething(){
        	service1 = new Service();
            return service1.runSomething();
        }
     }
    //client
    
    public class Client{
    	public static void main(String[] args){
        
        	IService proxy = new Proxy();
            System.out.println(proxy.runSomthing());
        }
    }

    Decorator Pattern(데코레이터 패턴) => OCP(개방 폐쇄 원칙) + DIP(의존 역전 원칙)

     

    메서드 호출의 반환값에 변화를 주기 위해 중간에 장식자를 두는 패턴

    말그대로 장식자인데 프록시 패턴은 제어 흐름을 변경하거나 별도의 로직 처리를 목적으로 하고, 반환값의 가감이 없지만 데코레이터 패턴은 클라이언트가 받는 반환값에 장식을 더한다.

     


    Singleton Pattern(싱글턴 패턴)

    객체를 하나만 만들어서 사용하는 패턴

    객체 하나만 만들어서 그것을 계속 재사용하는 패턴으로 new 키워드에 제약을 걸어야 하고, 만들어진 단일 객체를 반환할 수 있는 메서드가 필요하다.

     

    • 생성자에 private 접근 제어자 지정 => new 사용 X
    • 유일한 단일 객체를 반환할 수 있는 정적 메서드 필요
    • 유일한 단일 객체를 참조할 정적 참조 변수가 필요
    public class Singleton {
        static Singleton singltonObject;
        
        private Singleton(){}
        
        public static Singleton getInstance(){
            if(singltonObject==null){
                singltonObject = new Singleton();
            }
            return singltonObject;
        }
    }

     

    main에서 Singleton참조 변수들의 값을 출력해보면 다 같은 해시가 나오는것을 알 수 있다.

     

    단일 객체일 경우 결국 공유 객체로 사용되기 때문에 속성을 갖지 않는게 일반적이다. 다만 읽기 전용 속성은 문제가 되지 않는다. 또 단일 객체가 다른 단일 객체에 대한 참조를 속성으로 가지는것도 문제가 되지 않는다.

     

    댓글

Designed by Tistory.