前言一、门面模式Facade
1.定义2.案例说明3.代码实现 二、调停者模式Mediator
1.定义2.案例说明3.代码实现 总结
前言
本人对于设计模式的学习,仅供参考!
一、门面模式Facade 1.定义门面模式,是指提供一个统一的接口去访问多个子系统的多个不同的接口,它为子系统中一组接口提供一个统一的高层结构,使得子系统更容易使用。说的通俗一点就是对功能的封装,使用门面模式就例如:提供一个对外接口A(整体功能),将内部的一些功能(a,b,c)排列好,用户只需要调用这个接口即可。
2.案例说明你去线下门店购买服装,大致需要走的大致流程为挑选衣服、然后下单、付款、收货、当有问题时你可能还需要回来退货或者换货。现在门店的系统没有任何人管理,从试衣到提货走人,只有你自己一个人执行。也许你会感到并不麻烦,但是如果流程增多,又或者几十上百人都在执行这个流程,就会变得非常复杂冗余甚至很容易出错。但是如果是下面这种情形:
你会觉得非常清晰,对于客户来说不需要关心具体流程需要怎么实现,直接找导购即可,由导购帮你梳理带你执行需要的流程。即便新加了许多新的流程如会员注册、领取优惠券、选择折扣方式等,你通通不需要关心,所有过程全部已经封装好了。这就是现实生活中的一种门面模式。在代码中也是如此。
子系统角色中的类:
public class ModuleA {
//子系统提供给外部的使用方法
public void testA(){
System.out.println("下单");
}
//子系统内部模块之间的相互调用
public void test2(){ }
public void test3(){ }
}
public class ModuleB {
//子系统提供给外部的使用方法
public void testB(){
System.out.println("付款");
}
//子系统内部模块之间的相互调用
public void test2(){ }
public void test3(){ }
}
public class ModuleC {
public void testC(){
//子系统提供给外部的使用方法
System.out.println("退货");
}
//子系统内部模块之间的相互调用
public void test2(){ }
public void test3(){ }
}
public class ModuleD {
public void testD(){
//子系统提供给外部的使用方法
System.out.println("收款");
}
//子系统内部模块之间的相互调用
public void test2(){ }
public void test3(){ }
}
门面类:
public class Facade {
//满足客户端需要的功能例如:购买商品
public void test(){
ModuleA a=new ModuleA();
ModuleB b=new ModuleB();
a.testA();
b.testB();
}
//满足客户端需要的功能例如:退货
public void test2(){
ModuleC c=new ModuleC();
ModuleD d=new ModuleD();
c.testC();
d.testD();
}
}
客户端:
public class Main {
public static void main(String[] args) {
//购买商品
Facade facade=new Facade();
facade.test();
System.out.println("====================");
//退货
facade.test2();
}
}
当你购买商品时,只需要调用门面的test方法即可完成下单、付款。退货时只需要调用test2方法。
不需要再去亲自调用客户端中的下单、等等一些列的模块及其方法。而且可以有效地屏蔽其内部的细节,用于子系统内部之间相互调用的方法就不用暴露。
门面模式极大程度上对客户端和子系统内部进行解耦,如此子系统内部能更容易扩展和维护。也让子系统更加易用。
二、调停者模式Mediator 1.定义调停者模式用于模块间解耦,通过避免对象互相显式的指向对方,从而降低耦合。一个系统中,对象与对象之间不可避免发生各种通信,共同合作完成特定功能。我们们把这些对象称之为同事对象。通过把同事对象之间的交互逻辑提取、封装进调停者对象中,消除这些对象之间显式的引用让他们只通过调停者进行合作。降低耦合性,增加对象可复用性。
2.案例说明在不使用调停者模式的代码中,同事对象之间调用关系可能会非常复杂。如下:
四位玩家打游戏 ,相互耦合程度非常高,如果新加入一个新的对象,就要考虑,新对象与所有已有对象之间的相交互作用系统的扩展就会非常困难。逐渐形成网状结构,随着新加入的对象越多,扩展难度也就越来越大。因此,我们把这些交互集中在一个处于中间的角色中(调停者),就可以形成如下的情形。
在这种结构下,新加对象时我们只需要考虑,新家的对象怎么和调停者交互即可,大大降低了对象之间的耦合度,提高了可扩展性。我们利用一个简单地麻将案例,来实现一下调停者模式下的简易案例。
利用简易规则,即四个人打麻将,有一人胡牌则游戏结束。胡牌的玩家加三分,未胡牌的所有玩家扣一分。玩家为Vip玩家则胡牌加得的分数翻一倍,不考虑其他规则。
//抽象同事类
public abstract class AbstractPlayer {
//持有的调停者
protected Mediator mediator;
//分数
private int score;
//是否胡牌
private boolean finished;
public void setFinished(boolean finished) {
this.finished = finished;
}
public boolean isFinished() {
return finished;
}
//构造方法
public AbstractPlayer(Mediator mediator){
score=100;
this.mediator=mediator;
}
public int getScore(){
return score;
}
//如果胡牌则设置为true
public void finish(){
this.mediator.finish(this);
}
public void addPoint(int point){
this.score+=point;
}
public void cutPoint(int point){
this.score-=point;
}
}
//普通玩家
public class SimplePlayer extends AbstractPlayer {
//建立与调停者间的关系
public SimplePlayer(Mediator mediator) {
super(mediator);
this.mediator.registerPlayer(this);
}
}
//会员玩家
public class VipPlayer extends AbstractPlayer {
//建立与调停者间的关系
public VipPlayer(Mediator mediator) {
super(mediator);
this.mediator.registerPlayer(this);
}
}
//调停者
public class Mediator {
//建立容器收集对象
private List players=new ArrayList<>();
//将玩家注册
public void registerPlayer(AbstractPlayer player){
this.players.add(player);
}
public void finish(AbstractPlayer player) {
for (AbstractPlayer abstractPlayer : players) {
if(abstractPlayer==player){
abstractPlayer.setFinished(true);
if (abstractPlayer instanceof VipPlayer)
abstractPlayer.addPoint(6);
else
abstractPlayer.addPoint(3);
}else {
abstractPlayer.setFinished(false);
abstractPlayer.cutPoint(1);
}
}
}
}
public class Main {
public static void main(String[] args) {
Mediator mediator=new Mediator();
AbstractPlayer abstractPlayer1=new SimplePlayer(mediator);
AbstractPlayer abstractPlayer2=new SimplePlayer(mediator);
AbstractPlayer abstractPlayer3=new SimplePlayer(mediator);
AbstractPlayer abstractPlayer4=new VipPlayer(mediator);
//三号玩家胡牌
abstractPlayer3.finish();
System.out.println(abstractPlayer1.getScore());//99
System.out.println(abstractPlayer2.getScore());//99
System.out.println(abstractPlayer3.getScore());//104
System.out.println(abstractPlayer4.getScore());//99
}
}
调停者模式过度集中化会使我们把所有逻辑放入调停者,会导致其复杂无比,会导致调试困难,不利于管理和维护。
总结
门面模式针对于别人使用你的模块,这里面有对于你的顺序、业务有一定扩展修改的情况。
调停者模式更多的是在软件的内部,当软件的内部对象或模块之间相互通信时如何调用解耦。
两者非常相似,只是应对不同的位置而诞生。



