iT邦幫忙

2024 iThome 鐵人賽

DAY 28
0

介紹

抱怨一下
當初為什麼要選這個設計模式當最後一組題目呢
從早上十二點寫到早上五點半是不用睡覺了嗎

模式從這三個組成

  1. 中介者介面:Mediator
  2. 抽象類別:Colleague
  3. 中介者類別:ClassMediator

瞭解後這個設計模式滿好玩的
用實例來說比較好理解,功能需求如下:

  1. 有三個角色,分別是商場、家樂福和全家
  2. 商場可以對家樂福和全家廣播促銷活動
  3. 家樂福和全家可以互相傳訊息支援
  4. 家樂福和全家不能使用廣播

中介者模式實作

  1. 建立中介者介面
    • 訊息(send)
    • 廣播(sendAllStore)
public interface Mediator {
    String send(String name, String message, Caller sendTo);

    String sendAllStore(String name, String message);
}
  1. 建立抽象類別
public abstract class Caller {
    private final String name;
    private static final Mediator mediator = new CallerMediator();

    public Caller(String name) {
        this.name = name;
    }

    public String send(String message, Caller caller) {
        String send;
        send = mediator.send(this.name, message, caller);
        return send;
    }

    public String sendAllStore(String message) {
        String sendAllStore;
        sendAllStore = mediator.sendAllStore(this.name, message);
        return sendAllStore;
    }

    public String getName() {
        return name;
    }
}
  1. 建立中介者類別
    • 增加角色(addCaller)
    • 實作訊息(send)
    • 實作廣播(sendAllStore)
public class CallerMediator implements Mediator {

    public static final String MANAGER = "Manager";
    public static final String STAFF = "Staff";

    private static final List<Manager> managerList = new ArrayList<>();
    private static final List<Staff> staffList = new ArrayList<>();

    public String addCaller(Caller caller) {
        String text;
        if (MANAGER.equals(caller.getClass().getSimpleName())) {
            managerList.add((Manager) caller);
            text = "加入管理級廣播群組:" + caller.getName();
        } else if (STAFF.equals(caller.getClass().getSimpleName())) {
            staffList.add((Staff) caller);
            text = "加入員工級訊息群組:" + caller.getName();
        } else {
            text = "不加入聊天群組:" + caller.getName();
        }
        return text;
    }

    @Override
    public String send(String name, String message, Caller sendTo) {
        StringBuilder text;
        text = new StringBuilder();
        text.append(name);
        text.append(" ");
        text.append("發送訊息給 ");
        for (Caller caller : managerList) {
            if (caller.getName().equals(name)) {
                text.append(sendTo.getName());
            }
        }

        for (Caller caller : staffList) {
            if (caller.getName().equals(name)) {
                text.append(sendTo.getName());
            }
        }
        text.append(" | ");
        text.append("訊息內容:");
        text.append(message);

        return text.toString();
    }

    @Override
    public String sendAllStore(String name, String message) {
        StringBuilder text;
        text = new StringBuilder();
        text.append(name);
        text.append(" ");
        text.append("發送全體廣播:");
        text.append(message);
        text.append("\n");
        text.append("接收者:");

        for (Caller caller : managerList) {
            if (!caller.getName().equals(name)) {
                text.append(caller.getName());
                text.append("、");
            }
        }

        for (Caller caller : staffList) {
            if (!caller.getName().equals(name)) {
                text.append(caller.getName());
                text.append("、");
            }
        }

        return text.toString();
    }
}
  1. 增加管理者,有權限廣播和訊息
public class Manager extends Caller {

    public Manager(String name) {
        super(name);
    }
}
  1. 增加員工,只能傳送訊息
public class Staff extends Caller {

    public Staff(String name) {
        super(name);
    }

    @Override
    public String sendAllStore(String message) {
        StringBuilder text;
        text = new StringBuilder();
        text.append(getName());
        text.append(" 無法使用全體廣播");
        return text.toString();
    }
}

中介者模式測試

  1. 測試案例
public class JavaTest {

    @Test
    public void show() {

        StringBuilder text;
        text = new StringBuilder();
        text.append("\n");

        Caller mall = new Manager("商場");
        Caller carrefour = new Staff("家樂福");
        Caller familyMark = new Staff("全家");

        CallerMediator callerMediator = new CallerMediator();
        text.append(callerMediator.addCaller(mall));
        text.append("\n");
        text.append(callerMediator.addCaller(carrefour));
        text.append("\n");
        text.append(callerMediator.addCaller(familyMark));
        text.append("\n");
        text.append("\n");
        text.append(mall.sendAllStore("現在飲料買一送五"));
        text.append("\n");
        text.append("\n");
        text.append(mall.send("現在麵包買二送一,賣完了自己想辦法生出麵包", carrefour));
        text.append("\n");
        text.append(mall.send("現在便當打七折,賣完了自己想辦法生出便當", familyMark));
        text.append("\n");
        text.append(carrefour.send("借我一個員工支援收銀", familyMark));
        text.append("\n");
        text.append(familyMark.send("借你一個員工時薪 2000 元", carrefour));
        text.append("\n");
        text.append("\n");
        text.append(carrefour.sendAllStore("我不賣麵包啦,商場"));
        text.append("\n");
        text.append(familyMark.sendAllStore("我不賣便當啦,商場"));
        text.append("\n");

        assertEquals("測試", text.toString());
    }
}
  1. 執行測試
加入管理級廣播群組:商場
加入員工級訊息群組:家樂福
加入員工級訊息群組:全家

商場 發送全體廣播:現在飲料買一送五
接收者:家樂福、全家、

商場 發送訊息給 家樂福 | 訊息內容:現在麵包買二送一,賣完了自己想辦法生出麵包
商場 發送訊息給 全家 | 訊息內容:現在便當打七折,賣完了自己想辦法生出便當
家樂福 發送訊息給 全家 | 訊息內容:借我一個員工支援收銀
全家 發送訊息給 家樂福 | 訊息內容:借你一個員工時薪 2000 元

家樂福 無法使用全體廣播
全家 無法使用全體廣播

上一篇
113/27 - 狀態模式(State)- Kotlin
下一篇
113/29 - 中介者模式(Mediator)- Kotlin
系列文
肯定會斷賽之在 Android 開發使用設計模式30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言