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