SMALL

브리지 패턴은 객체의 확장성을 향상하기 위한 패턴으로, 객체에서 동작을 처리하는 구현부확장을 위한 추상부를 분리한다.

출처: https://ko.wikipedia.org/wiki/%EB%B8%8C%EB%A6%AC%EC%A7%80_%ED%8C%A8%ED%84%B4

상속을 통해서 객체의 계층을 분리하고 기능을 확장하지만 강력한 결합 관계와 불필요한 메서드도 상속에 같이 포함된다는 단점을 갖고 있다.

 

이러한 상속의 문제점은 브리지 패턴을 응용하여 해결할 수 있다.

브리지 패턴을 적용하려면 4개의 구성 요소가 필요하다.

  • Implementor
    • Abstraction의 기능을 구현하기 위한 인터페이스 정의
  • ConcreateImplementor
    • 실제 기능을 구현
  • Abstract
    • 추상부 계층의 최상위 클래스
      구현부에 해당하는 클래스를 인스턴스를 가지고 해당 인스턴스를 통해 구현부분의 메서드를 호출
  • refinedAbstract
    • 추상부 계층에서 새로운 부분을 확장한 클래스

상속은 강력한 결합을 가진다 -> 위임을 통해 느슨한 결합 관계로 변경 ( 복합 객체 구조 )

 

Inplementor

public interface HelloInterface {
    public String greeting();
}

 

ConcreateImplementor

public class Korean implements HelloInterface {

    @Override
    public String greeting() {
        return "안녕하세요";
    }

}

public class English implements HelloInterface {

    @Override
    public String greeting() {
        return "Hello";
    }

}

 

패턴 설계 1

public class Language {
    public HelloInterface ko;
    public HelloInterface en;

    public void setEnglish(HelloInterface en) {
        this.en = en;
    }

    public void setKorean(HelloInterface ko) {
        this.ko = ko;
    }
}

복합 객체인 Language는 2개의 구현 클래스를 연결 ( 위임을 통해서 )

 

브리지 패턴은 복합 객체를 다시 재정의하여 추상 계층화된 구조이다.

위의 설계 1을 변형하여 구성 클래스의 연결 부분을 추상 계층으로 변경

추상화 변경을 실행하는 이유 : 각각의 계층이 독립적으로 확장/변경 가능하도록 하기 위해서

 

브리지 패턴은 기능을 처리하는 클래스구현을 담당하는 추상 클래스로 구별한다.

구현뿐 아니라 추상화도 독립적 변경이 필요할 때 브리지 패턴을 사용한다.

 

브리지는 구현 계층추상 계층 두 곳을 연결하는 다리라는 의미이다.

브리지 패턴을 적용하기 위해서는 계층을 잘 분리하는 것이 중요하다.

그리고 분리된 추상적 개념과 구현 계층을 연결해야 한다.

 

abstract

public abstract class LanguageAbstr {
    public HelloInterface lan;

    abstract public String greeting();
}

 

refinedAbstract

public class Message extends LanguageAbstr {

    public Message(HelloInterface lan) {
        this.lan = lan;
    }

    @Override
    public String greeting() {
        // bridge part
        return this.lan.greeting();
    }

}

추상 클래스는 상위 클래스와 하위 클래스 사이에서 역할을 분담한다

역할을 분담하는 추상 클래스의 계층은 새로운 기능을 생성하는 것이 아니라 기존의 기능을 분리하여 계층화한다.

 

브리지 패턴은 기존 시스템에 부수적인 새로운 기능들을 지속적으로 추가할 때 사용하면 유용한 패턴이다.

브리지 패턴은 새로운 인터페이스를 정의하여 기존 프로그램의 변경 없이 기능을 확장할 수 있다.

 

 

어댑터 패턴, 브리지 패턴

어댑터 패턴과 브리지 패턴이 유사해 보이기도 한다.

어댑터 패턴이 완성된 코드를 통합하고 결합할 때 사용되는 패턴이라면,

브리지 패턴은 처음 설계 단계에서 추상화 및 구현을 위해 확장을 고려한 패턴이라고 할 수 있다.

 

LIST
SMALL

어댑터 패턴은 코드를 재사용하기 위해 구조를 변경하는 패턴이다.

구조 패턴 중에 가장 간단하다.

 

이전에 만들어진 코드를 재활용하기 위해서는 대부분의 경우 변환 ( 변형 ) 작업이 필요하다.

기존 코드를 직접 수정이 불가능한 경우에는 

기존 코드를 감싸서 보정 코드를 만들어 사용한다.

즉 보정 코드를 통해 문제점을 우회가 가능하다

 

기존의 소스에서 보정된 코드가 많으면 가독성도 떨어지고 유지보수도 힘들어진다.

이러한 경우 별도의 객체를 생성하여 보정을 처리하는 것이 좋다.

이처럼 보정만을 위해 설계된 객체를 어댑터 패턴이라고 한다.

 

어댑터 패턴은 수정 불가능한 문제를 분리된 객체로 쉽게 해결할 수 있도록 도와준다.

어댑터 패턴을 설계할 때는 연관성이 없는 2개의 객체를 묶어 인터페이스를 통일화한다.

그리고 통일화된 변경 인터페이스로 기존의 코드를 재사용한다.

 

어댑터 패턴은 코드를 재사용하기 위한 인터페이스를 처리하고 인터페이스를 활용해 보정 코드를 작성한다.

( 기존의 클래스를 새로운 클래스로 감싼다 )

출처: https://jusungpark.tistory.com/22

어댑터 패턴의 종류

어댑터는 다른 객체의 구조를 내가 원하는 인터페이스 방식으로 개선한다

구조를 개선하는 방법은 클래스의 상속을 이용하는 방법

구성을 이용하는 방법 2가지이다

 

클래스 어댑터

클래스 어댑터를 사용하기 위해서는 다중 상속이 필요하다

( 자바는 단일 상속만 지원.. )

 

객체 어댑터

객체의 의존성을 이용해 문제를 해결

객체 어댑터는 내부적으로 객체를 재구성한다 -> 기존 객체는 복합 객체로 변환 

 

장점

객체를 구성으로 결합하면 느슨한 연결 방식으로 보다 많은 유연성을 확보할 수 있다

 

단점

객체를 구성으로 결합하면 어댑터는 클라이언트에서 사용하는 인터페이스 방식으로 메서드를 새로 생성해야 한다

 

기존 코드

public class Math {

	public float twoTime(float num) {
		
		return num * 2;
	}
	
	public float halfTime(float num) {
		
		return num / 2;
	}
}

float를 매개변수로 받는다

 

하지만 실 사용자 코드에서는 int를 넘겨주고 싶다

이러한 경우에 어댑터 패턴 적용해보기

 

우선 인터페이스 생성

public interface Adapter {
	public int twiceOf(int num);
	public int halfOf(int num);
}

실제 구현체

public class Objects implements Adapter{

	private Math adapter;
	
	public Objects() {
		this.adapter = new Math();
	}
	@Override
	public int twiceOf(int num) {
		int rst = (int) this.adapter.twoTime(num);
		return rst;
	}

	@Override
	public int halfOf(int num) {
		int rst = (int) this.adapter.halfTime(num);
		return rst;
	}

}

 

사용자 코드

	public static void main(String[] args) {
		Math math = new Math();
		float rst = math.twoTime(2.1f);
		float rst1 = math.twoTime(2.2f);
		System.out.println(rst);
		System.out.println(rst1);
		
		Objects obj = new Objects();
		System.out.println(obj.twiceOf(33));
		System.out.println(obj.halfOf(33));
		
	}
LIST

+ Recent posts