栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

门面模式和装饰者模式(设计模式之门面模式和调停者模式)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

门面模式和装饰者模式(设计模式之门面模式和调停者模式)

文章目录

前言一、门面模式Facade

1.定义2.案例说明3.代码实现 二、调停者模式Mediator

1.定义2.案例说明3.代码实现 总结


前言

本人对于设计模式的学习,仅供参考!

一、门面模式Facade 1.定义

门面模式,是指提供一个统一的接口去访问多个子系统的多个不同的接口,它为子系统中一组接口提供一个统一的高层结构,使得子系统更容易使用。说的通俗一点就是对功能的封装,使用门面模式就例如:提供一个对外接口A(整体功能),将内部的一些功能(a,b,c)排列好,用户只需要调用这个接口即可。

2.案例说明

你去线下门店购买服装,大致需要走的大致流程为挑选衣服、然后下单、付款、收货、当有问题时你可能还需要回来退货或者换货。现在门店的系统没有任何人管理,从试衣到提货走人,只有你自己一个人执行。也许你会感到并不麻烦,但是如果流程增多,又或者几十上百人都在执行这个流程,就会变得非常复杂冗余甚至很容易出错。但是如果是下面这种情形:


你会觉得非常清晰,对于客户来说不需要关心具体流程需要怎么实现,直接找导购即可,由导购帮你梳理带你执行需要的流程。即便新加了许多新的流程如会员注册、领取优惠券、选择折扣方式等,你通通不需要关心,所有过程全部已经封装好了。这就是现实生活中的一种门面模式。在代码中也是如此。

3.代码实现

子系统角色中的类:

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.案例说明

在不使用调停者模式的代码中,同事对象之间调用关系可能会非常复杂。如下:


四位玩家打游戏 ,相互耦合程度非常高,如果新加入一个新的对象,就要考虑,新对象与所有已有对象之间的相交互作用系统的扩展就会非常困难。逐渐形成网状结构,随着新加入的对象越多,扩展难度也就越来越大。因此,我们把这些交互集中在一个处于中间的角色中(调停者),就可以形成如下的情形。


在这种结构下,新加对象时我们只需要考虑,新家的对象怎么和调停者交互即可,大大降低了对象之间的耦合度,提高了可扩展性。我们利用一个简单地麻将案例,来实现一下调停者模式下的简易案例。

3.代码实现

利用简易规则,即四个人打麻将,有一人胡牌则游戏结束。胡牌的玩家加三分,未胡牌的所有玩家扣一分。玩家为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

    }
}

调停者模式过度集中化会使我们把所有逻辑放入调停者,会导致其复杂无比,会导致调试困难,不利于管理和维护。


总结

门面模式针对于别人使用你的模块,这里面有对于你的顺序、业务有一定扩展修改的情况。
调停者模式更多的是在软件的内部,当软件的内部对象或模块之间相互通信时如何调用解耦。
两者非常相似,只是应对不同的位置而诞生。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/776160.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号