图解设计模式 -- 简单化

本文详细解析了设计模式中的Facade模式和Mediator模式。Facade模式用于简化复杂系统的接口,提供一个统一的入口,减少客户端与系统组件间的交互复杂性。Mediator模式则用于协调多个对象之间的通信,避免对象间直接耦合,提高代码可维护性。文中通过代码示例展示了这两种模式的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码Github连接 :https://github.com/tangbi123/Tab-Design-Pattern

Facade

可以为互相关联在一起地错综复杂地类整理出高层接口(API),让系统对外只有一个简单的接口(API),并且考虑系统内部各个类之间地责任关系和依赖关系,按照正确地顺序调用各个类。

示例

在这里插入图片描述
在这里插入图片描述
文件结构
在这里插入图片描述

代码清单

1)Database

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;
    }
}

mailData.txt

hyuki@hyuki.com=Hiroshi Yuki
hanako@hyuki.com=Hanako Sato
tomura@hyuki.com=Tomura
mamoru@hyuki.com=Mamoru Takahashi

2)HtmlWriter

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>");
    }

    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)PageMaker

public class PageMaker {
    private PageMaker(){}

    public static void makeWelcomePage(String mailAddr, String filename){
        try{
            Properties mailProp = Database.getProperties("src/Facade/mailData");
            String username = mailProp.getProperty(mailAddr);
            HtmlWriter writer = new HtmlWriter(new FileWriter(filename));
            writer.title("Welcome to " + username + " 's page!");
            writer.paragraph(username + "欢迎来到" + username + " 的主页");
            writer.paragraph("等着你的邮件哦");
            writer.mailto(mailAddr,username);
            writer.close();
            System.out.println(filename + "is created for" + mailAddr + "("
             + username + ")");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4)Main

public class FacadeMain {
    public static void main(String[] args) {
        PageMaker.makeWelcomePage("hyuki@hyuki.com", "welcom.html");
    }
}

角色

在这里插入图片描述

  1. Facade(窗口) =》 PageMaker
    代表构成系统的许多其他角色的“简单窗口”,向系统外部提供高层接口(API)。
    2)构成系统的许多其他角色 =》 Database、HtmlWriter
    这些角色各自完成i及的工作,他们并不知道Facade角色;Facade角色调用其他角色进行工作,但是其他角色不会调用Facade角色。
    3)Client(请求者)
    负责调用Facade角色。

思路要点

Facade角色到底做什么工作

Facade模式可以让复杂的东西看起来简单。
重点是 接口(API)变少了。直接使用一个接口(API)的Facade角色,综合了其他角色的 类和方法、调用顺序。

递归地使用Facade模式

假设现在有几个持有Facade角色类的集合,那么我们可以通过整合这几个集合来引入新的Facade角色 =》 递归地使用Facade。

开发人员不愿意创建Facade角色的原因

Mediator(仲裁者)

当发生麻烦事情的时候,通知仲裁者;当发生设计全体组员的事情时,也通知仲裁者。
当仲裁者下达指示时,组员会立即执行。
团队组员之间不在互相沟通并私自做出决定,而是发生任何事都想仲裁者报告。
仲裁者站在整个团队角度上对组员上报的事情做出决定。

仲裁者成为 Mediator,各组员被称为Colleague。

示例

在这里插入图片描述
不让各个对象之间互相通信,而是增加一个仲裁者角色,让哥哥对象之间互相通信,而是增加一个仲裁者角色,让他们各自和仲裁者通信,然后将控制显示的逻辑处理交给仲裁者负责。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码清单

1)Mediator

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

2)Colleague

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

3)ColleagueCheckbox

public class ColleagueCheckbox extends Checkbox implements ItemListener,Colleague {
    private Mediator mediator;

    public ColleagueCheckbox(String label, CheckboxGroup group, boolean state) throws HeadlessException {
        super(label, group, state);
    }

    @Override
    public void setMediator(Mediator mediator) {
        this.mediator = mediator;
    }

    @Override
    public void setColleagueEnabled(boolean enabled) {
        setEnabled(enabled);
    }

    @Override
    public void itemStateChanged(ItemEvent e) {
        mediator.colleagueChanged();
    }
}

4)ColleagueButton

public class ColleagueButton extends Button implements Colleague {
    private Mediator mediator;
    public ColleagueButton(String caption){
        super(caption);
    }
    @Override
    public void setMediator(Mediator mediator) {
        this.mediator = mediator;
    }

    @Override
    public void setColleagueEnabled(boolean enabled) {
        setEnabled(enabled);
    }
}

5)ColleagueTextField

public class ColleagueTextField extends TextField implements TextListener,Colleague {
    private Mediator mediator;

    public ColleagueTextField(String text, int columns) throws HeadlessException {
        super(text, columns);
    }

    @Override
    public void setMediator(Mediator mediator) {
        this.mediator = mediator;
    }

    @Override
    public void setColleagueEnabled(boolean enabled) {
        setEnabled(enabled);
        setBackground(enabled? Color.white : Color.lightGray);
    }

    @Override
    public void textValueChanged(TextEvent e) {
        mediator.colleagueChanged();
    }
}

6)LoginFrame

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();
        add(checkGuest);
        add(checkLogin);
        add(new Label("Username:"));
        add(textUser);
        add(new Label("Password:"));
        add(textPass);
        add(buttonOk);
        add(buttonCancel);

        colleagueChanged();
        pack();
        show();
    }
    @Override
    public void createColleagues() {
        CheckboxGroup g = new CheckboxGroup();
        checkGuest = new ColleagueCheckbox("Guest",g,true);
        checkLogin = new ColleagueCheckbox("Login",g,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);
    }

    @Override
    public void colleagueChanged() {
        if(checkGuest.getState()){
            textUser.setColleagueEnabled(false);
            textPass.setColleagueEnabled(false);
            buttonOk.setColleagueEnabled(false);
        }
        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);
        }
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println(e.toString());
        System.exit(0);
    }
}

7)Main

public class MediatorMain {
    public static void main(String[] args) {
        new LoginFrame("Mediator Sample");
    }
}

角色

在这里插入图片描述
1)Mediator(仲裁者)
负责定义与Colleague角色进行通信和做出决定的接口(API)
2)ConcreteMediator =》 LoginFrame
负责实现Mediator角色的接口,负责实际做出决定
3)Colleague
负责定义与Mediator角色进行通信的接口(API)
4)ConcreteColleague
负责实现Colleague角色的接口api

思路要点

当发生分散灾难

修改 collegueChanged,调试Bug。
这段逻辑分散在 ConcreteColleague中,会难以调试。

通信线路的增加

哪些角色可以复用

ConcreteColleague可以复用,但ConcreteMediator很难服用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值