当前位置: 首页 > news >正文

java设计模式-外观模式

外观模式(facade)

基本介绍

1、外观模式也叫过程模式,外观模式为子系统中的一组接口提供一个一致的界面,次模式定义一个高层接口,这个接口是的这一子系统更加容易使用。
2、外观模式通过定义一个一直的接口,用以屏蔽内部子系统的细节,使得调用端只需要跟这个接口发生调用,而无需关心这个子系统的内部细节。
在这里插入图片描述

原理图

1、外观类(Facade):为调用端提供统一的调用接口,外观类知道那些子类系统负责。
2、调用者(Client):外观接口的调用者
3、子系统的几盒:之模块或者子系统,处理Facade对象指派的任务。他是功能的实际提供者。

@Slf4j
public class DVDPlayer {
    //使用饿汉式单例模式
    private static DVDPlayer instance = new DVDPlayer();
    public static DVDPlayer getInstance() {
        return instance;
    }
    public void on() {
        log.info(" dvd on ");
    }
    public void off() {
        log.info(" dvd off ");
    }
    public void play() {
        log.info(" dvd is play");
    }
    public void pause() {
        log.info(" dvd is pause");
    }
}
@Slf4j
public class Popcorn {
    //饿汉式
    private static Popcorn popcorn = new Popcorn();
    public static Popcorn getInstance() {
        return popcorn;
    }
    public void on() {
        log.info(" popcorn on ");
    }
    public void off() {
        log.info(" popcorn off ");
    }
    public void pop() {
        log.info(" popcorn is poping");
    }
}
@Slf4j
public class Projector {
    //饿汉式
    private static Projector projector = new Projector();

    public static Projector getInstance() {
        return projector;
    }
    public void on() {
        log.info(" projector on ");
    }
    public void off() {
        log.info(" projector off ");
    }
    public void focus() {
        log.info(" projector is focus");
    }
}
@Slf4j
public class Screen {
    //使用饿汉式单例模式
    private static Screen instance = new Screen();
    public static Screen getInstance() {
        return instance;
    }
    public void up() {
        log.info(" Screen up ");
    }
    public void on() {
        log.info(" Screen on ");
    }
    public void down() {
        log.info(" Screen down ");
    }
}
@Slf4j
public class Stereo {
    //饿汉式
    private static Stereo projector = new Stereo();
    public static Stereo getInstance() {
        return projector;
    }
    public void on() {
        log.info(" Stereo on ");
    }
    public void off() {
        log.info(" Stereo off ");
    }
    public void up() {
        log.info(" Stereo is up");
    }
}
@Slf4j
public class TheaterLight {
    //使用饿汉式单例模式
    private static TheaterLight instance = new TheaterLight();
    public static TheaterLight getInstance() {
        return instance;
    }
    public void on() {
        log.info(" TheaterLight up ");
    }
    public void dim() {
        log.info(" TheaterLight dim ");
    }
    public void bright() {
        log.info(" TheaterLight bright ");
    }
}
//=================外观模式类=======================
public class HomeTheaterFacade {
    private TheaterLight theaterLight;
    private Popcorn popcorn;
    private Projector projector;
    private Stereo stereo;
    private Screen screen;
    private DVDPlayer dvdPlayer;
    //构造器
    public HomeTheaterFacade() {
        this.theaterLight = TheaterLight.getInstance();
        this.popcorn = Popcorn.getInstance();
        this.stereo = Stereo.getInstance();
        this.screen = Screen.getInstance();
        this.dvdPlayer = DVDPlayer.getInstance();
        this.projector = Projector.getInstance();
    }
    //分成四个步骤
    public void ready(){
        popcorn.on();
        popcorn.pop();
        screen.down();
        projector.on();
        stereo.on();
        dvdPlayer.on();
        theaterLight.dim();
    }
    public void play(){
        dvdPlayer.play();
    }
    public void pause(){
        dvdPlayer.pause();
    }
    public void end(){
        popcorn.off();
        theaterLight.bright();
        screen.up();
        projector.off();
        stereo.off();
        dvdPlayer.off();
    }
}
public class Client {
    public static void main(String[] args) {

        HomeTheaterFacade facade=new HomeTheaterFacade();
        facade.ready();
        facade.play();
        facade.pause();
        facade.end();
    }
}

源码中的使用(MyBatis的Configuration去创建MetaObject)对象使用到外观模式
在这里插入图片描述

public class Configuration {
    public MetaObject newMetaObject(Object object) {
            return MetaObject.forObject(object, this.objectFactory, this.objectWrapperFactory, this.reflectorFactory);
        }
}
public class MetaObject {
    private final Object originalObject;
    private final ObjectWrapper objectWrapper;
    private final ObjectFactory objectFactory;
    private final ObjectWrapperFactory objectWrapperFactory;
    private final ReflectorFactory reflectorFactory;

    private MetaObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory, ReflectorFactory reflectorFactory) {
        this.originalObject = object;
        this.objectFactory = objectFactory;
        this.objectWrapperFactory = objectWrapperFactory;
        this.reflectorFactory = reflectorFactory;
        if (object instanceof ObjectWrapper) {
            this.objectWrapper = (ObjectWrapper)object;
        } else if (objectWrapperFactory.hasWrapperFor(object)) {
            this.objectWrapper = objectWrapperFactory.getWrapperFor(this, object);
        } else if (object instanceof Map) {
            this.objectWrapper = new MapWrapper(this, (Map)object);
        } else if (object instanceof Collection) {
            this.objectWrapper = new CollectionWrapper(this, (Collection)object);
        } else {
            this.objectWrapper = new BeanWrapper(this, object);
        }

    }

    public static MetaObject forObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory, ReflectorFactory reflectorFactory) {
        return object == null ? SystemMetaObject.NULL_META_OBJECT : new MetaObject(object, objectFactory, objectWrapperFactory, reflectorFactory);
    }

外观模式注意事项

1、外观模式 对外屏蔽了子系统的细节,因此外观模式降低了客户端对子系统适用的复杂性。
2、外观模式对客户端子系统的耦合关系-解耦,让子系统内部的模块更易维护和扩展。
3、通过合理的使用外观模式,可以帮我们更好的划分访问的层次
4、当系统需要进行分层设计时,可以考虑使用facade模式。
5、在维护一个遗留的大型系统时,可能这个系统已经变得非常难以维护和扩展,此时可以考虑为新系统开发一个Facade类,来提供遗留系统的比较清晰简单的接口。
让新系统与Facade类交互,提高复用性。

6、不能过多的或者不合理的使用外观模式,使用外国模式好,还是直接调用模块好,要以让系统有层次,利于维护为目的。

相关文章:

  • 【人工智能】深入解析自注意力机制:AI大语言模型的核心引擎
  • 球类(继承和多态)
  • configMAX_SYSCALL_INTERRUPT_PRIORITY和configKERNEL_INTERRUPT_PRIORITY
  • 力扣刷题DAY10(动态规划-线性DP)
  • rcore day6
  • [ctfshow web入门] web23
  • cdw2: TypeScript
  • 牛客网:树的高度 ← 根节点为 0 号节点
  • 脚本启动 Java 程序
  • 工程师 - FTDI SPI converter
  • async/await 异步编程
  • 将飞帆制作的网页作为 div 集成到自己的网页中
  • C语言之九九乘法表
  • PCL拟合空间3D圆周 fit3DCircle
  • 数智孪生:制造业转型的驱动力
  • 4月8日日记
  • YOLOv11改进 | YOLOv11引入MobileNetV4
  • I/O进程3
  • 【STL】list介绍(附与vector的比较)
  • 硅谷甄选项目笔记