中介者模式:它通过特殊的中介器对象使程序组件之间进行间接通信,从而减少程序组件之间的耦合。
而在Java 中 使用 譬如 通常用于 GUI 组件之间的通信。在MVC 模式中,controller 中中介者的同义词。
而java自带核心类库中有该模式的一些例子:
例如:
java.util.Timer中的所有scheduleAtFixedRate
java.lang.reflect.Method#invoke() 等
上代码
public interface LadyHunter {
int age();
String selfTag();
String menTag();
ManSolicitor waitingForMatchMan(List<ManSolicitor> manSolicitor);
boolean notice(ManSolicitor man);
String userName();
}
public interface ManSolicitor {
String userName();
LadyHunter waitingForMatchMan(List<LadyHunter> ladyHunter);
String selfTag();
String ladyTag();
int age();
boolean notice(LadyHunter lady);
}
媒婆:
public class MarriageBroker {
private static List<ManSolicitor> manSolicitors = new ArrayList();
private static List<LadyHunter> ladyHunters = new ArrayList();
public static void register(ManSolicitor manSolicitor) {
manSolicitors.add(manSolicitor);
}
public static void register(LadyHunter ladyHunter) {
ladyHunters.add(ladyHunter);
}
public void match() {
System.out.println("婚姻中介开始撮合!");
manSolicitors.stream().forEach(ms ->{
String ladyTag = ms.ladyTag();
List<LadyHunter> matchLadyHunters = ladyHunters.stream().filter(ladyHunter -> ladyHunter.selfTag().equals(ladyTag)).collect(Collectors.toList());
if(matchLadyHunters != null && matchLadyHunters.size() != 0) {
//男方中意了一位女士
LadyHunter matchLady = ms.waitingForMatchMan(matchLadyHunters);
//通知女方是否可以同意
boolean isAgree = matchLady.notice(ms);
if(isAgree && ms.notice(matchLady)) {
System.out.println("最后双方都确认了, "+ms.userName()+" 和 "+ matchLady.userName()+" 确认恋爱关系");
}
}
});
}
}
public class AMan implements ManSolicitor {
public AMan() {
MarriageBroker.register(this);
}
@Override
public LadyHunter waitingForMatchMan(List<LadyHunter> ladyHunter) {
Random random = new Random();
int index = random.nextInt(ladyHunter.size());
return ladyHunter.get(index);
}
@Override
public String selfTag() {
// TODO Auto-generated method stub
return "工资高、学历高、26岁以下、身高:175cm";
}
@Override
public String ladyTag() {
return "贤惠,漂亮,身高 170cm";
}
@Override
public int age() {
// TODO Auto-generated method stub
return 25;
}
@Override
public boolean notice(LadyHunter lady) {
return this.ladyTag().equals(lady.selfTag());
}
@Override
public String userName() {
// TODO Auto-generated method stub
return "A 先生";
}
}
public class BMan implements ManSolicitor {
public BMan() {
MarriageBroker.register(this);
}
@Override
public LadyHunter waitingForMatchMan(List<LadyHunter> ladyHunter) {
Random random = new Random();
int index = random.nextInt(ladyHunter.size());
return ladyHunter.get(index);
}
@Override
public String selfTag() {
// TODO Auto-generated method stub
return "工资一般、能做一桌好吃的、本科、29岁以下、身高:180cm";
}
@Override
public String ladyTag() {
return "贤惠、体贴,身高:175cm";
}
@Override
public int age() {
// TODO Auto-generated method stub
return 28;
}
@Override
public boolean notice(LadyHunter lady) {
return this.ladyTag().equals(lady.selfTag());
}
@Override
public String userName() {
// TODO Auto-generated method stub
return "B 先生";
}
}
public class CLady implements LadyHunter {
public CLady() {
MarriageBroker.register(this);
}
@Override
public int age() {
// TODO Auto-generated method stub
return 24;
}
@Override
public String selfTag() {
// TODO Auto-generated method stub
return "贤惠、体贴,身高:175cm";
}
@Override
public String menTag() {
// TODO Auto-generated method stub
return "工资一般、能做一桌好吃的、本科、29岁以下、身高:180cm";
}
@Override
public ManSolicitor waitingForMatchMan(List<ManSolicitor> manSolicitor) {
Random random = new Random();
int index = random.nextInt(manSolicitor.size());
return manSolicitor.get(index);
}
@Override
public boolean notice(ManSolicitor man) {
// TODO Auto-generated method stub
return this.menTag().equals(man.selfTag());
}
@Override
public String userName() {
// TODO Auto-generated method stub
return "C 仙女";
}
}
public class DLady implements LadyHunter {
public DLady() {
MarriageBroker.register(this);
}
@Override
public int age() {
// TODO Auto-generated method stub
return 25;
}
@Override
public String selfTag() {
// TODO Auto-generated method stub
return "贤惠,漂亮,身高 170cm";
}
@Override
public String menTag() {
// TODO Auto-generated method stub
return "工资高、学历高、26岁以下、身高:175cm";
}
@Override
public ManSolicitor waitingForMatchMan(List<ManSolicitor> manSolicitor) {
Random random = new Random();
int index = random.nextInt(manSolicitor.size());
return manSolicitor.get(index);
}
@Override
public boolean notice(ManSolicitor man) {
return this.menTag().equals(man.selfTag());
}
@Override
public String userName() {
return "D 仙女";
}
}
测试:
public static void main(String[] args) {
MarriageBroker MarriageBroker = new MarriageBroker();
ManSolicitor aMan = new AMan();
ManSolicitor bMan = new BMan();
LadyHunter cLady = new CLady();
LadyHunter dLady = new DLady();
MarriageBroker.match();
}
输出结果:
婚姻中介开始撮合!
最后双方都确认了, A 先生 和 D 仙女 确认恋爱关系
最后双方都确认了, B 先生 和 C 仙女 确认恋爱关系
在增加一个mvc 案例:
public interface Component {
void setMediator(Mediator mediator);
String getName();
}
public class AddButton extends JButton implements Component {
private Mediator mediator;
public AddButton() {
super("Add");
}
@Override
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
@Override
protected void fireActionPerformed(ActionEvent actionEvent) {
mediator.addNewNote(new Note());
}
@Override
public String getName() {
return "AddButton";
}
}
public class DeleteButton extends JButton implements Component {
private Mediator mediator;
public DeleteButton() {
super("Del");
}
@Override
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
@Override
protected void fireActionPerformed(ActionEvent actionEvent) {
mediator.deleteNote();
}
@Override
public String getName() {
return "DelButton";
}
}
public class Filter extends JTextField implements Component {
private Mediator mediator;
private ListModel listModel;
public Filter() {}
@Override
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
@Override
protected void processComponentKeyEvent(KeyEvent keyEvent) {
String start = getText();
searchElements(start);
}
public void setList(ListModel listModel) {
this.listModel = listModel;
}
private void searchElements(String s) {
if (listModel == null) {
return;
}
if (s.equals("")) {
mediator.setElementsList(listModel);
return;
}
ArrayList<Note> notes = new ArrayList<>();
for (int i = 0; i < listModel.getSize(); i++) {
notes.add((Note) listModel.getElementAt(i));
}
DefaultListModel<Note> listModel = new DefaultListModel<>();
for (Note note : notes) {
if (note.getName().contains(s)) {
listModel.addElement(note);
}
}
mediator.setElementsList(listModel);
}
@Override
public String getName() {
return "Filter";
}
}
public class List extends JList implements Component {
private Mediator mediator;
private final DefaultListModel LIST_MODEL;
public List(DefaultListModel listModel) {
super(listModel);
this.LIST_MODEL = listModel;
setModel(listModel);
this.setLayoutOrientation(JList.VERTICAL);
Thread thread = new Thread(new Hide(this));
thread.start();
}
@Override
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
public void addElement(Note note) {
LIST_MODEL.addElement(note);
int index = LIST_MODEL.size() - 1;
setSelectedIndex(index);
ensureIndexIsVisible(index);
mediator.sendToFilter(LIST_MODEL);
}
public void deleteElement() {
int index = this.getSelectedIndex();
try {
LIST_MODEL.remove(index);
mediator.sendToFilter(LIST_MODEL);
} catch (ArrayIndexOutOfBoundsException ignored) {}
}
public Note getCurrentElement() {
return (Note)getSelectedValue();
}
@Override
public String getName() {
return "List";
}
private class Hide implements Runnable {
private List list;
Hide(List list) {
this.list = list;
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(300);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
if (list.isSelectionEmpty()) {
mediator.hideElements(true);
} else {
mediator.hideElements(false);
}
}
}
}
}
public class SaveButton extends JButton implements Component {
private Mediator mediator;
public SaveButton() {
super("Save");
}
@Override
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
@Override
protected void fireActionPerformed(ActionEvent actionEvent) {
mediator.saveChanges();
}
@Override
public String getName() {
return "SaveButton";
}
}
public class TextBox extends JTextArea implements Component {
private Mediator mediator;
@Override
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
@Override
protected void processComponentKeyEvent(KeyEvent keyEvent) {
mediator.markNote();
}
@Override
public String getName() {
return "TextBox";
}
}
public class Title extends JTextField implements Component {
private Mediator mediator;
@Override
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
@Override
protected void processComponentKeyEvent(KeyEvent keyEvent) {
mediator.markNote();
}
@Override
public String getName() {
return "Title";
}
}
定义通用的中介者接口
public interface Mediator {
void addNewNote(Note note);
void deleteNote();
void getInfoFromList(Note note);
void saveChanges();
void markNote();
void clear();
void sendToFilter(ListModel listModel);
void setElementsList(ListModel list);
void registerComponent(Component component);
void hideElements(boolean flag);
void createGUI();
}
public class Editor implements Mediator {
private Title title;
private TextBox textBox;
private AddButton add;
private DeleteButton del;
private SaveButton save;
private List list;
private Filter filter;
private JLabel titleLabel = new JLabel("Title:");
private JLabel textLabel = new JLabel("Text:");
private JLabel label = new JLabel("Add or select existing note to proceed...");
/**
* Here the registration of components by the mediator.
*/
@Override
public void registerComponent(Component component) {
component.setMediator(this);
switch (component.getName()) {
case "AddButton":
add = (AddButton)component;
break;
case "DelButton":
del = (DeleteButton)component;
break;
case "Filter":
filter = (Filter)component;
break;
case "List":
list = (List)component;
this.list.addListSelectionListener(listSelectionEvent -> {
Note note = (Note)list.getSelectedValue();
if (note != null) {
getInfoFromList(note);
} else {
clear();
}
});
break;
case "SaveButton":
save = (SaveButton)component;
break;
case "TextBox":
textBox = (TextBox)component;
break;
case "Title":
title = (Title)component;
break;
}
}
/**
* Various methods to handle requests from particular components.
*/
@Override
public void addNewNote(Note note) {
title.setText("");
textBox.setText("");
list.addElement(note);
}
@Override
public void deleteNote() {
list.deleteElement();
}
@Override
public void getInfoFromList(Note note) {
title.setText(note.getName().replace('*', ' '));
textBox.setText(note.getText());
}
@Override
public void saveChanges() {
try {
Note note = (Note) list.getSelectedValue();
note.setName(title.getText());
note.setText(textBox.getText());
list.repaint();
} catch (NullPointerException ignored) {}
}
@Override
public void markNote() {
try {
Note note = list.getCurrentElement();
String name = note.getName();
if (!name.endsWith("*")) {
note.setName(note.getName() + "*");
}
list.repaint();
} catch (NullPointerException ignored) {}
}
@Override
public void clear() {
title.setText("");
textBox.setText("");
}
@Override
public void sendToFilter(ListModel listModel) {
filter.setList(listModel);
}
@SuppressWarnings("unchecked")
@Override
public void setElementsList(ListModel list) {
this.list.setModel(list);
this.list.repaint();
}
@Override
public void hideElements(boolean flag) {
titleLabel.setVisible(!flag);
textLabel.setVisible(!flag);
title.setVisible(!flag);
textBox.setVisible(!flag);
save.setVisible(!flag);
label.setVisible(flag);
}
@Override
public void createGUI() {
JFrame notes = new JFrame("Notes");
notes.setSize(960, 600);
notes.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JPanel left = new JPanel();
left.setBorder(new LineBorder(Color.BLACK));
left.setSize(320, 600);
left.setLayout(new BoxLayout(left, BoxLayout.Y_AXIS));
JPanel filterPanel = new JPanel();
filterPanel.add(new JLabel("Filter:"));
filter.setColumns(20);
filterPanel.add(filter);
filterPanel.setPreferredSize(new Dimension(280, 40));
JPanel listPanel = new JPanel();
list.setFixedCellWidth(260);
listPanel.setSize(320, 470);
JScrollPane scrollPane = new JScrollPane(list);
scrollPane.setPreferredSize(new Dimension(275, 410));
listPanel.add(scrollPane);
JPanel buttonPanel = new JPanel();
add.setPreferredSize(new Dimension(85, 25));
buttonPanel.add(add);
del.setPreferredSize(new Dimension(85, 25));
buttonPanel.add(del);
buttonPanel.setLayout(new FlowLayout());
left.add(filterPanel);
left.add(listPanel);
left.add(buttonPanel);
JPanel right = new JPanel();
right.setLayout(null);
right.setSize(640, 600);
right.setLocation(320, 0);
right.setBorder(new LineBorder(Color.BLACK));
titleLabel.setBounds(20, 4, 50, 20);
title.setBounds(60, 5, 555, 20);
textLabel.setBounds(20, 4, 50, 130);
textBox.setBorder(new LineBorder(Color.DARK_GRAY));
textBox.setBounds(20, 80, 595, 410);
save.setBounds(270, 535, 80, 25);
label.setFont(new Font("Verdana", Font.PLAIN, 22));
label.setBounds(100, 240, 500, 100);
right.add(label);
right.add(titleLabel);
right.add(title);
right.add(textLabel);
right.add(textBox);
right.add(save);
notes.setLayout(null);
notes.getContentPane().add(left);
notes.getContentPane().add(right);
notes.setResizable(false);
notes.setLocationRelativeTo(null);
notes.setVisible(true);
}
}
public class Note {
private String name;
private String text;
public Note() {
name = "New note";
}
public void setName(String name) {
this.name = name;
}
public void setText(String text) {
this.text = text;
}
public String getName() {
return name;
}
public String getText() {
return text;
}
@Override
public String toString() {
return name;
}
}
测试:
public static void main(String[] args) {
Mediator mediator = new Editor();
mediator.registerComponent(new Title());
mediator.registerComponent(new TextBox());
mediator.registerComponent(new AddButton());
mediator.registerComponent(new DeleteButton());
mediator.registerComponent(new SaveButton());
mediator.registerComponent(new List(new DefaultListModel()));
mediator.registerComponent(new Filter());
mediator.createGUI();
}