门面模式是将原有的复杂逻辑提取到 一个统一的接口,简化客户对逻辑的使用。它是被客户所感知的,而原有的复杂逻辑则被隐藏了起来。对象相互作用的方式,使得这些对象不必互相明显引用。从而使它们可以较松中介者模式包装了一系列散地耦合.
Facade模式组织相关逻辑,通过统一的接口暴露给客户端
public class Alarm implements Triggerable {
@Override
public void Activate() {
DebugLog.log("activate the Alarm");
}
@Override
public void Deactiviate() {
DebugLog.log("deactivate the Alarm");
}
public void ring()
{
DebugLog.log("ringing");
}
public void StopRing()
{
DebugLog.log("stop ring");
}
}
public class Camara implements Switchable {
@Override
public void turnOn() {
DebugLog.log("turn on camera");
}
@Override
public void turnOff() {
DebugLog.log("turn off camera");
}
public void rotate(int degree)
{
DebugLog.log("change the camera degree");
}
}
public class Light implements Switchable {
@Override
public void turnOn() {
DebugLog.log("turn on light" );
}
@Override
public void turnOff() {
DebugLog.log("turn off light" );
}
public void changeBulb()
{
DebugLog.log("change the light bulb" );
}
}
public class Sensor implements Triggerable {
@Override
public void Activate() {
DebugLog.log("activate the sensor");
}
@Override
public void Deactiviate() {
DebugLog.log("deactivate the sensor");
}
}
public interface Switchable {
public void turnOn();
public void turnOff();
}
public interface Triggerable {
public void Activate();
public void Deactiviate();
}
public class SecurityFacade {
private static Camara foreCamera, backCamera;
private static Light middleLight, toiletLight;
private static Sensor entrySensor,exitSensor;
private static Alarm receptionRoomAlerm;
public void init(){
foreCamera = new Camara();
backCamera = new Camara();
middleLight = new Light();
toiletLight = new Light();
entrySensor = new Sensor();
exitSensor = new Sensor();
receptionRoomAlerm = new Alarm();
}
public SecurityFacade() {
init();
}
public void Activiate()
{
foreCamera.turnOn();
backCamera.turnOn();
middleLight.turnOn();
toiletLight.turnOn();
entrySensor.Activate();
exitSensor.Activate();
receptionRoomAlerm.Activate();
}
public void Deactiviate()
{
foreCamera.turnOff();
backCamera.turnOff();
middleLight.turnOff();
toiletLight.turnOff();
entrySensor.Deactiviate();
exitSensor.Deactiviate();
receptionRoomAlerm.Deactiviate();
}
}
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
SecurityFacade facade = new SecurityFacade();
facade.Activiate();
facade.Deactiviate();
}
}
假如开发一套安保系统,系统startup 和shutdown时,需要将camera,light, sensor进行
相关操作,你应该将相关操作封装一个方法里面,而不是散落在各地,由客户端随意调用。
Mediator实际通过manager来操作实际对象:
public class CDDriver extends Parts {
private String data;
public CDDriver(Mediator mediator) {
super(mediator);
}
public String getData() {
return data;
}
public void readCD(){
this.data = "Video Data,Sound Data";
this.getMediator().changed(this);
}
}
public class CPU extends Parts {
private String videoData;
private String soundData;
public CPU(Mediator mediator) {
super(mediator);
}
public String getVideoData() {
return videoData;
}
public String getSoundData() {
return soundData;
}
public void executeData(String data){
String[] ss = data.split(",");
this.videoData = ss[0];
this.soundData = ss[1];
this.getMediator().changed(this);
}
}
public interface Mediator {
public void changed(Parts colleague);
}
public abstract class Parts {
private final Mediator mediator;
public Parts(Mediator mediator){
this.mediator = mediator;
}
public Mediator getMediator(){
return mediator;
}
}
public class SoundCard extends Parts {
public SoundCard(Mediator mediator){
super(mediator);
}
public void soundData(String data){
System.out.println("画外音:" + data);
}
}
public class VideoCard extends Parts {
public VideoCard(Mediator mediator) {
super(mediator);
}
public void showData(String data){
System.out.println("你正在观看的是:" + data);
}
}
public class MainBoard implements Mediator {
private CDDriver cdDriver;
private CPU cpu;
private VideoCard videoCard;
private SoundCard soundCard;
@Override
public void changed(Parts colleague) {
if(colleague == cdDriver){
this.operateCDDriverReadData((CDDriver)colleague);
}else if(colleague == cpu){
this.operateCPU((CPU)colleague);
}
}
public void setCdDriver(CDDriver cdDriver) {
this.cdDriver = cdDriver;
}
public void setCpu(CPU cpu) {
this.cpu = cpu;
}
public void setVideoCard(VideoCard videoCard) {
this.videoCard = videoCard;
}
public void setSoundCard(SoundCard soundCard) {
this.soundCard = soundCard;
}
public void operateCDDriverReadData(CDDriver cd){
String data = cd.getData();
this.cpu.executeData(data);
}
public void operateCPU(CPU cpu){
String videoData = cpu.getVideoData();
String soundData = cpu.getSoundData();
this.videoCard.showData(videoData);
this.soundCard.soundData(soundData);
}
}
通过上面的代码可以看出,MainBoard作为manager协调cpu,cdd,显卡的操作,
如果要通过cpu,add,显卡之间相互调用,逻辑会太复杂。但是例子存在另外一个
问题,mainboard中如下代码是不是太丑陋:
if(colleague == cdDriver){
this.operateCDDriverReadData((CDDriver)colleague);
}else if(colleague == cpu){
this.operateCPU((CPU)colleague);
}
重构如下:
public class CDDriver extends Part {
public CDDriver(Mediator mediator, int key) {
super(mediator, key);
}
private String data;
public String getData() {
return data;
}
@Override
public void action(String data) {
this.data = "Video Data,Sound Data";
}
}
public class CPU extends Part {
public CPU(Mediator mediator, int key) {
super(mediator, key);
}
private String videoData;
private String soundData;
public String getVideoData() {
return videoData;
}
public String getSoundData() {
return soundData;
}
@Override
public void action(String data) {
String[] ss = data.split(",");
this.videoData = ss[0];
this.soundData = ss[1];
}
}
public class MainBoard implements Mediator {
private Map<Integer, Part> partMap = new HashMap<Integer, Part>();
private Map<Integer, Part[]> partsMap = new HashMap<Integer, Part[]>();
private boolean registerIsDone = false;
@Override
public void changed(Part colleague) {
if (!registerIsDone)
composeLogicMap();
Part[] parts = getPartsByKey(colleague.getKey());
int size = parts.length;
for (int index = 0; index < size; index++) {
Part apart = parts[index];
apart.change("1111,2222");
}
registerIsDone = true;
}
@Override
public void register(int key, Part colleague) {
partMap.put(key, colleague);
}
public void composeLogicMap() {
Part[] cdParts = new Part[] { partMap.get(Mediator.PARTSTYPE.CPU) };
partsMap.put(Mediator.PARTSTYPE.CDDriver, cdParts);
Part[] cpuParts = new Part[] {partMap.get(Mediator.PARTSTYPE.VideoCard),partMap.get(Mediator.PARTSTYPE.SoundCard) };
partsMap.put(Mediator.PARTSTYPE.CDDriver, cpuParts);
}
public Part[] getPartsByKey(int key) {
Part[] parts = partsMap.get(key);
if (parts == null)
parts = new Part[] { Part.NULL };
return parts;
}
}
public interface Mediator {
public void changed(Part colleague);
public void register(int key,Part colleague);
public interface PARTSTYPE
{
int CDDriver=0;
int CPU =1;
int SoundCard=2;
int VideoCard =3;
}
}
public abstract class Part {
private final Mediator mediator;
private final int key;
public int getKey() {
return key;
}
public Mediator getMediator() {
return mediator;
}
public Part(Mediator mediator, int key) {
super();
this.mediator = mediator;
this.key = key;
if (mediator != null)
mediator.register(key, this);
}
public abstract void action(String data);
protected void change(String data) {
action(data);
mediator.changed(this);
}
public static final Part NULL = new Part(null, 1) {
@Override
public void action(String data) {
}
@Override
protected void change(String data) {
}
};
}
public class SoundCard extends Part {
public SoundCard(Mediator mediator, int key) {
super(mediator, key);
}
public void soundData(String data){
super.change(data);
}
@Override
public void action(String data) {
System.out.println("画外音:" + data);
}
}
public class VideoCard extends Part {
public VideoCard(Mediator mediator, int key) {
super(mediator, key);
}
public void showData(String data){
super.change(data);
}
@Override
public void action(String data) {
System.out.println("你正在观看的是:" + data);
}
}
public class Test {
public static void main(String[] args) {
MainBoard mediator = new MainBoard();
Part cd = new CDDriver(mediator,Mediator.PARTSTYPE.CDDriver);
new CPU(mediator,Mediator.PARTSTYPE.CPU);
new VideoCard(mediator,Mediator.PARTSTYPE.VideoCard);
new SoundCard(mediator,Mediator.PARTSTYPE.SoundCard);
cd.change("dddd");
}
}