Java

[Design Pattern] 창구 패턴(Facade Pattern)과 중개자 패턴(Mediator Pattern)

구루싸 2020. 7. 13. 22:49
반응형
SMALL

오늘은 서두 없이

바로 학습을 진행하겠습니다

이번 학습 주제는

창구 패턴(Facade Pattern)과

중개자 패턴(Mediator)입니다

프로그램을 만들다보면

많은 클래스들이 생성되고

서로 관계를 맺으면서 복잡해지는데

상호 관련된 많은 클래스를

적절하게 관리해주는 창구를

하나 준비하면 좋을 것입니다

창구 패턴은

복잡하게 얽혀 있는 것을

정리해서 높은 레벨의

인터페이스를 제공하는 패턴입니다

언제나 처럼

창구 패턴의 역할들을

정리하고 시작하겠습니다

역할설명
Facade(창구)시스템을 구성하고 있는 많은 역할에 대한 단순한 창구로서 높은 레벨에서 단순한 인터페이스를 시스템 외부에 제공

(시스템을 구성하는 그 밖의 많은 역할들)
이 역할들이 Facade 역할을 호출하는 일은 없고 각각의 임무를 수행
Client(의뢰인)Facade 역할을 이용하는 역할

역할들만 보았을 때

어렵지 않을 것 같네요

직접 구현해보겠습니다

1. 클래스(Class) Database.java

package facadePattern.pageMaker;
import java.util.*;
import java.io.*;
public class Database {
	private Database() {
	}
	public static Properties getProperties(String dbname) {
		String filename = dbname + ".txt";
		Properties prop = new Properties();
		try {
			prop.load(new FileInputStream(filename));
		} catch(IOException e) {
			System.out.println("Warning: " + filename + " is not found.");
		}
		return prop;
	}
}

2. 클래스(Class) HtmlWriter.java

package facadePattern.pageMaker;
import java.io.*;
public class HtmlWriter {
	private Writer writer;
	public HtmlWriter(Writer writer) {
		this.writer = writer;
	}
	public void title(String title) throws IOException {
		writer.write("<html>");
		writer.write("<head>");
		writer.write("<title>" + title + "</title>");
		writer.write("</head>");
		writer.write("<body>\n");
		writer.write("<h1>" + title + "</h1>\n");
	}
	public void paragraph(String msg) throws IOException {
		writer.write("<p>" + msg + "</p>\n");
	}
	public void link(String href, String caption) throws IOException {
		paragraph("<a href=\"" + href + "\">" + caption + "</a>");
	}
	public void mailto(String mailaddr, String username) throws IOException {
		link("mailto:" + mailaddr, username);
	}
	public void close() throws IOException {
		writer.write("</body>");
		writer.write("</html>\n");
		writer.close();
	}
}

3. 클래스(Class) PageMaker.java

package facadePattern.pageMaker;
import java.io.*;
import java.util.*;
public class PageMaker {
	private PageMaker() {
	}
	public static void makeWelcomePage(String mailaddr, String filename) {
		try {
			Properties mailprop = Database.getProperties("maildata");
			String username = mailprop.getProperty(mailaddr);
			HtmlWriter writer = new HtmlWriter(new FileWriter(filename));
			writer.title("Welcome to " + username + " 's page!");
			writer.paragraph(username + "의 tistory에 오신 걸 환영합니다.");
			writer.paragraph("메일을 기다리고 있습니다.");
			writer.mailto(mailaddr, username);
			writer.close();
			System.out.println(filename + " is created for " + mailaddr + " (" + username + ")");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

4. 클래스(Class) Test.java

import facadePattern.pageMaker.*;
public class Test {
	public static void main(String[] args) {
		/* Facade Pattern */
		PageMaker.makeWelcomePage("yssa@tistory.com", "welcome.html");
	}
}

이번 구현은 비교적 쉬웠는데

구현보다 중요한 것은

이 패턴이 왜 필요한지 아는 것이겠죠

이 패턴의 핵심은

인터페이스를 적게 하는 것입니다

인터페이스가 적다는 것은

외부와의 결합이

그 만큼 적다는 것이고

이는 패키지를 부품으로써

재이용하기 쉽게 해준다는 것을
의미합니다

다음으로 중개자(Mediator) 패턴을

학습해보겠습니다

중개자 패턴은

중개자라는 단어로도

짐작가듯이

중개인이 있어서

중개인만이

동료(Colleague)에게

지시를 내리는 패턴입니다

다수의 오브젝트 사이를

조정해야할 경우에 유용하겠네요

그럼 중개자 패턴의

역할들을 정리하겠습니다

역할설명
Mediator(중개자)Colleague 역할과 통신을 해서 조정을 실행하기 위한 인터페이스를 결정
Concrete Mediator(구체적인 중개자)Mediator 역할의 인터페이스를 구현해서 실제의 조정을 실행
Colleague(동료)Mediator 역할과 통신을 실행할 인터페이스를 결정
Concrete Colleague(구체적인 동료)Colleague 역할의 인터페이스를 구현

이제 구현을 해보겠습니다

1. 인터페이스(Interface) Mediator.java

package mediatorPattern;

public interface Mediator {
	public abstract void createColleagues();
	public abstract void colleagueChanged();
}

2. 인터페이스(Interface) Colleague.java

package mediatorPattern;

public interface Colleague {
	public abstract void setMediator(Mediator mediator);
	public abstract void setColleagueEnabled(boolean enabled);
}

3. 클래스(Class) ColleagueButton.java

package mediatorPattern;
import java.awt.Button;
public class ColleagueButton extends Button implements Colleague {
	private Mediator mediator;
	public ColleagueButton(String caption) {
		super(caption);
	}
	public void setMediator(Mediator mediator) {
		this.mediator = mediator;
	}
	public void setColleagueEnabled(boolean enabled) {
		setEnabled(enabled);
	}
}

4. 클래스(Class) ColleagueCheckbox.java

package mediatorPattern;
import java.awt.*;
import java.awt.event.*;
public class ColleagueCheckbox extends Checkbox implements ItemListener, Colleague {
	private Mediator mediator;
	public ColleagueCheckbox(String caption, CheckboxGroup group, boolean state) {
		super(caption, group, state);
	}
	public void setMediator(Mediator mediator) {
		this.mediator = mediator;
	}
	public void setColleagueEnabled(boolean enabled) {
		setEnabled(enabled);
	}
	public void itemStateChanged(ItemEvent e) {
		mediator.colleagueChanged();
	}
}

5. 클래스(Class) ColleagueTextField.java

package mediatorPattern;
import java.awt.*;
import java.awt.event.*;
public class ColleagueTextField extends TextField implements TextListener, Colleague {
	private Mediator mediator;
	public ColleagueTextField(String text, int columns) {
		super(text, columns);
	}
	public void setMediator(Mediator mediator) {
		this.mediator = mediator;
	}
	public void setColleagueEnabled(boolean enabled) {
		setEnabled(enabled);
		setBackground(enabled ? Color.white : Color.lightGray);
	}
	public void textValueChanged(TextEvent e) {
		mediator.colleagueChanged();
	}
}

6. 클래스(Class) LoginFrame.java

package mediatorPattern;
import java.awt.*;
import java.awt.event.*;
public class LoginFrame extends Frame implements ActionListener, Mediator {
	private ColleagueCheckbox checkGuest;
	private ColleagueCheckbox checkLogin;
	private ColleagueTextField textUser;
	private ColleagueTextField textPass;
	private ColleagueButton buttonOk;
	private ColleagueButton buttonCancel;
	
	public LoginFrame(String title) {
		super(title);
		setBackground(Color.lightGray);
		setLayout(new GridLayout(4, 2));
		createColleagues();
		addColleagues();
		colleagueChanged();
		pack();
		show();
	}
	public void createColleagues() {
		CheckboxGroup grp = new CheckboxGroup();
		checkGuest = new ColleagueCheckbox("Guest", grp, true);
		checkLogin = new ColleagueCheckbox("Login", grp, false);
		textUser = new ColleagueTextField("", 10);
		textPass = new ColleagueTextField("", 10);
		textPass.setEchoChar('*');
		buttonOk = new ColleagueButton("OK");
		buttonCancel = new ColleagueButton("Cancel");
		checkGuest.setMediator(this);
		checkLogin.setMediator(this);
		textUser.setMediator(this);
		textPass.setMediator(this);
		buttonOk.setMediator(this);
		buttonCancel.setMediator(this);
		checkGuest.addItemListener(checkGuest);
		checkLogin.addItemListener(checkLogin);
		textUser.addTextListener(textUser);
		textPass.addTextListener(textPass);
		buttonOk.addActionListener(this);
		buttonCancel.addActionListener(this);
	}
	public void addColleagues() {
		add(checkGuest);
		add(checkLogin);
		add(new Label("Username:"));
		add(textUser);
		add(new Label("Password:"));
		add(textPass);
		add(buttonOk);
		add(buttonCancel);
	}
	public void colleagueChanged() {
		if ( checkGuest.getState() ) {
			textUser.setColleagueEnabled(false);
			textPass.setColleagueEnabled(false);
			buttonOk.setColleagueEnabled(true);
		} else {
			textUser.setColleagueEnabled(true);
			userpassChanged();
		}
	}
	private void userpassChanged() {
		if ( textUser.getText().length() > 0 ) {
			textPass.setColleagueEnabled(true);
			if ( textPass.getText().length() > 0 ) {
				buttonOk.setColleagueEnabled(true);
			} else {
				buttonOk.setColleagueEnabled(false);
			}
		} else {
			textPass.setColleagueEnabled(false);
			buttonOk.setColleagueEnabled(false);
		}
	}
	public void actionPerformed(ActionEvent e) {
		System.out.println(e.toString());
		System.exit(0);
	}
}

7. 클래스(Class) Test.java

import mediatorPattern.*;
public class Test {
	public static void main(String[] args) {
		/* Mediator Pattern */
		new LoginFrame("Mediator Sample");
	}
}

위의 코드를 보면

LoginFrame 클래스는

어플리케이션에 대한

의존성이 높아

재사용하기 어렵지만

다른 Concrete Colleague 역할의

클래스들은 재사용하는 것이

가능해보이네요

또 Facade 패턴은

일방적으로 다른 역할을

이용해서 높은 레벨의

인터페이스를 만드는데

Mediator 패턴은

Mediator와 Colleague가

서로 통신을 하고 있는

차이가 있습니다

이번 학습은 이것으로 마치겠습니다

그럼 이만-_-

반응형
LIST