在这里,我还有另一篇关于设计模式的文章- 外观设计模式。甲门面 目的是使用通过隐藏一个复杂的系统的复杂性,以提供简单的界面。
Facade Design Pattern
我们可能还会有多个Facade对象,一个对象处理几个子系统,另一个对象处理一些其他子系统。
我希望我们现在清楚什么是Facade?为了更清楚地了解它以及在我们的代码中使用Facade,让我们以我们通常在家中使用的家用电器为例。
Home Appliance Application using Facade Design Pattern 为了更容易地理解Facade的用法,我在这里使用示例示例应用程序代码(在Command Design Pattern中使用了示例代码)。我只做了一些必要的更改,并添加了其他设备和功能的代码,以使示例更加清晰有趣。
该示例还帮助您将Facade与Command Design Pattern进行比较。
Code for Appliance class:
package org.trishinfotech.facade.devices; public abstract class Appliance implements Comparable<Appliance> { protected String name; protected boolean status; public Appliance(String name) { super(); if (name == null || name.trim().isEmpty()) { new IllegalArgumentException("Appliance name is mandatory for Home Automation"); } this.name = name; } public String name() { return name; } // define operations for appliance public void on() { if (status) { System.out.printf("'%s' is already turned on!\n", name); } else { status = true; System.out.printf("Turning On '%s'\n", name); } } public void off() { if (!status) { System.out.printf("'%s' is already turned off!\n", name); } else { status = false; System.out.printf("Turning Off '%s'\n", name); } } // Appliance should be compared only on name. @Override public int compareTo(Appliance other) { return this.name.compareToIgnoreCase(other.name); } }
我在这里定义了一些常见的操作,例如“开”和“关”。
粉丝等级代码:
package org.trishinfotech.facade.devices; public abstract class Fan extends Appliance { public static int TOP_SPEED = 4; public static int LOWEST_SPEED = 1; protected int currentSpeed = 1; public Fan(String name) { super(name); } // define operations for fan public void increase() { if (currentSpeed < TOP_SPEED) { currentSpeed++; System.out.printf("Encreasing Speed of '%s' to '%d'.\n", name, currentSpeed); } else { System.out.printf("'%s' is already running at top speed!\n", name); } } public void decrease() { if (currentSpeed > LOWEST_SPEED) { currentSpeed--; System.out.printf("Decreasing Speed of '%s' to '%d'.\n", name, currentSpeed); } else { System.out.printf("'%s' is laready running at lowest speed!\n", name); } } }
我在此处添加了“增加”和“减少”速度等操作,以及它的“设备”子类型。
Code for Light class:
package org.trishinfotech.facade.devices; public abstract class Light extends Appliance { public Light(String name) { super(name); } }
由于我们已经定义了“开”和“关”,因此无需进行其他操作。
SoundBar 类的代码:
package org.trishinfotech.facade.devices; public abstract class SoundBar extends Appliance { public static int TOP_VOLUME = 30; public static int LOWEST_VOLUME = 0; protected String soundMode; protected int currentVolume = 1; protected int volumeWhenMute; public SoundBar(String name) { super(name); } // define operations for SoundBar public void setSoundMode(String soundMode) { this.soundMode = soundMode; System.out.printf("Setting Sound-Mode of '%s' to '%s'.\n", name, soundMode); } public void increaseVolume() { if (currentVolume < TOP_VOLUME) { currentVolume++; System.out.printf("Encreasing volume of '%s' to '%d'.\n", name, currentVolume); } else { System.out.printf("'%s' is already on top volume!\n", name); } } public void decreaseVolume() { if (currentVolume > LOWEST_VOLUME) { currentVolume--; System.out.printf("Decreasing volume of '%s' to '%d'.\n", name, currentVolume); } else { System.out.printf("'%s' is already on mute!\n", name); } } public void volume(int volume) { if (volume >= LOWEST_VOLUME && volume <= TOP_VOLUME) { currentVolume = volume; System.out.printf("Setting volume of '%s' to '%d'.\n", name, currentVolume); } else { System.out.printf("Volume of '%s' is supports range between '%d' and '%d'!\n", name, LOWEST_VOLUME, TOP_VOLUME); } } public void mute() { if (currentVolume != LOWEST_VOLUME) { volumeWhenMute = currentVolume; currentVolume = 0; System.out.printf("Putting '%s' on mute!\n", name); } else { currentVolume = volumeWhenMute; System.out.printf("Unmuting '%s'. Setting volume back to '%d'!\n", name, currentVolume); } } public String soundMode() { return soundMode; } }
在这里,我为“声音模式”和“增加”,“减少”,“设置”音量和“静音”等操作添加了代码。
Code for TV class:
package org.trishinfotech.facade.devices; public abstract class TV extends Appliance { public static int TOP_VOLUME = 30; public static int LOWEST_VOLUME = 0; public static int TOP_CHANNEL_NO = 999; public static int LOWEST_CHANNEL_NO = 1; protected int currentVolume = 1; protected int currentChannel = 1; protected int volumeWhenMute; public TV(String name) { super(name); } // define operations for TV public void increaseVolume() { if (currentVolume < TOP_VOLUME) { currentVolume++; System.out.printf("Encreasing volume of '%s' to '%d'.\n", name, currentVolume); } else { System.out.printf("'%s' is already on top volume!\n", name); } } public void decreaseVolume() { if (currentVolume > LOWEST_VOLUME) { currentVolume--; System.out.printf("Decreasing volume of '%s' to '%d'.\n", name, currentVolume); } else { System.out.printf("'%s' is already on mute!\n", name); } } public void mute() { if (currentVolume != LOWEST_VOLUME) { volumeWhenMute = currentVolume; currentVolume = 0; System.out.printf("Putting '%s' on mute!\n", name); } else { currentVolume = volumeWhenMute; System.out.printf("Unmuting '%s'. Setting volume back to '%d'!\n", name, currentVolume); } } public void increaseChannel() { if (currentChannel < TOP_CHANNEL_NO) { currentChannel++; System.out.printf("Encreasing channel of '%s' to '%d'.\n", name, currentChannel); } else { System.out.printf("'%s' is already showing channel '%d'!\n", name, currentChannel); } } public void decreaseChannel() { if (currentChannel > LOWEST_CHANNEL_NO) { currentChannel--; System.out.printf("Decreasing channel of '%s' to '%d'.\n", name, currentChannel); } else { System.out.printf("'%s' is already showing channel '%d'!\n", name, currentChannel); } } }
我添加了“增加/减少音量”,“增加/减少频道”和“静音”之类的操作。
CoffeeMaker类的代码:
package org.trishinfotech.facade.devices.kitchen; import org.trishinfotech.facade.devices.Appliance; public class CoffeeMaker extends Appliance { public CoffeeMaker() { super("CoffeeMaker"); } }
ElectricGrill类的代码:
package org.trishinfotech.facade.devices.kitchen; import org.trishinfotech.facade.devices.Appliance; public class ElectricGrill extends Appliance { protected int temp; public ElectricGrill() { super("ElectricGrill"); } public void setTemp(int temp) { this.temp = temp; System.out.printf("Setting '%s' temprature to '%d'.\n", name, temp); } public int temperature() { return temp; } }
在这里,我添加了设置“温度”的操作。
KitchenLight类的代码:
package org.trishinfotech.facade.devices.kitchen; import org.trishinfotech.facade.devices.Light; public class KitchenLight extends Light { public KitchenLight() { super("KitchenLight"); } }
Code for Microwave class:
package org.trishinfotech.facade.devices.kitchen; import org.trishinfotech.facade.devices.Appliance; public class Microwave extends Appliance { protected int temp; protected int time; protected boolean grillOn = false; public Microwave() { super("Microwave"); } public void grillOn() { this.grillOn = true; System.out.printf("Turning on grill of '%s'.\n", name); } public void grillOff() { this.grillOn = false; System.out.printf("Turning off grill of '%s'.\n", name); } public void setOnPreHeat(int temp, int time) { this.temp = temp; this.time = time; System.out.printf("Setting '%s' on Pre-Heat, temprature '%d', time '%d' minutes.\n", name, temp, time); } public void bake(String pizzaName, int temp, int time) { this.temp = temp; this.time = time; System.out.printf("Baking '%s' in '%s' for temprature '%d', time '%d' minutes.\n", pizzaName, name, temp, time); } public int temp() { return temp; } public int time() { return time; } }
在这里,我定义了诸如“烧烤开/关”,“预加热”和“烘焙”之类的操作。
Code for Refrigerator class:
package org.trishinfotech.facade.devices.kitchen; import org.trishinfotech.facade.devices.Appliance; public class Refrigerator extends Appliance { protected static final String PARTY = "party"; protected static final String NORMAL = "normal"; protected String mode = NORMAL; public Refrigerator() { super("Refrigerator"); } public void partyMode() { mode = PARTY; System.out.printf("Setting '%s' Cooling to 'Party'.\n", name); } public void normalMode() { mode = NORMAL; System.out.printf("Setting '%s' Cooling to 'Normal'.\n", name); } }
在这里,我定义了“模式”(如“派对”)进行快速冷却,并定义了“普通”(针对正常冷却)。
LivingRoomFan类的代码:
package org.trishinfotech.facade.devices.livingroom; import org.trishinfotech.facade.devices.Fan; public class LivingRoomFan extends Fan { public LivingRoomFan() { super("LivingRoomFan"); } }
LivingRoomFireTV4KStick类的代码:
package org.trishinfotech.facade.devices.livingroom; import org.trishinfotech.facade.devices.Appliance; import org.trishinfotech.facade.devices.TV; public class LivingRoomFireTV4KStick extends Appliance { protected TV tv; protected String appName; protected String contentName; public LivingRoomFireTV4KStick(TV tv) { super("LivingRoomFireTV4KStick"); this.tv = tv; } // define operations for Fire TV Stick 4K public void openApp(String appName) { this.appName = appName; System.out.printf("Opening '%s' on '%s'.\n", appName, name); } public void selectContent(String contentName) { this.contentName = contentName; System.out.printf("Searching '%s' on '%s'.\n", contentName, appName); } public void play() { System.out.printf("Playing '%s' on '%s'.\n", contentName, appName); } public void closeApp() { System.out.printf("Closing '%s' on '%s'.\n", appName, name); } public TV tv() { return tv; } public String appName() { return appName; } public String contentName() { return contentName; } }
在这里,我添加了“打开应用程序”,“关闭应用程序”,“搜索内容”和“播放”之类的操作。
LivingRoomLight类的代码:
package org.trishinfotech.facade.devices.livingroom; import org.trishinfotech.facade.devices.Light; public class LivingRoomLight extends Light { protected int brightness = 50; public LivingRoomLight() { super("LivingRoomLight"); } public void dim() { brightness = 20; System.out.printf("Dimming '%s'.\n", name); } public void bright() { brightness = 100; System.out.printf("Setting brightness of '%s' to '%d'.\n", name, brightness); } }
在这里,我定义了通过使用“暗淡”和“明亮”来控制灯光亮度的操作。
LivingRoomSoundBar类的代码:
package org.trishinfotech.facade.devices.livingroom; import org.trishinfotech.facade.devices.SoundBar; import org.trishinfotech.facade.devices.TV; public class LivingRoomSoundBar extends SoundBar { protected TV tv; public LivingRoomSoundBar(TV tv) { super("LivingRoomSoundBar"); this.tv = tv; } public TV tv() { return tv; } }
LivingRoomTV类的代码:
package org.trishinfotech.facade.devices.livingroom; import org.trishinfotech.facade.devices.TV; public class LivingRoomTV extends TV { protected String source; public LivingRoomTV() { super("LivingRoomTV"); } public void setSource(String source) { this.source = source; System.out.printf("Setting Source of '%s' to '%s'.\n", name, source); } public String source() { return source; } }
现在,在定义了所有设备及其操作之后,就该使用Facade Design Pattern了。假设我们喜欢在家里与朋友和家人一起参加周末聚会。由于我们在家中拥有用于娱乐和餐饮的各种设备,因此我们编写了一个HomeFacade 来定义“周末家庭聚会”的操作。
HomeFacade类的代码:
package org.trishinfotech.facade; import java.util.List; import org.trishinfotech.facade.devices.Fan; import org.trishinfotech.facade.devices.Light; import org.trishinfotech.facade.devices.SoundBar; import org.trishinfotech.facade.devices.TV; import org.trishinfotech.facade.devices.kitchen.CoffeeMaker; import org.trishinfotech.facade.devices.kitchen.ElectricGrill; import org.trishinfotech.facade.devices.kitchen.KitchenLight; import org.trishinfotech.facade.devices.kitchen.Microwave; import org.trishinfotech.facade.devices.kitchen.Refrigerator; import org.trishinfotech.facade.devices.livingroom.LivingRoomFan; import org.trishinfotech.facade.devices.livingroom.LivingRoomFireTV4KStick; import org.trishinfotech.facade.devices.livingroom.LivingRoomLight; import org.trishinfotech.facade.devices.livingroom.LivingRoomSoundBar; import org.trishinfotech.facade.devices.livingroom.LivingRoomTV; public class HomeFacade { Fan fan; LivingRoomFireTV4KStick stick; Light livingRoomLight; SoundBar soundBar; TV tv; CoffeeMaker maker; ElectricGrill grill; Light kitchenLight; Microwave microwave; Refrigerator refrigerator; public HomeFacade() { super(); fan = new LivingRoomFan(); tv = new LivingRoomTV(); stick = new LivingRoomFireTV4KStick(tv); livingRoomLight = new LivingRoomLight(); soundBar = new LivingRoomSoundBar(tv); maker = new CoffeeMaker(); grill = new ElectricGrill(); kitchenLight = new KitchenLight(); microwave = new Microwave(); refrigerator = new Refrigerator(); } public void playMovieOnNetflix(String movieName) { fan.on(); fan.increase(); livingRoomLight.on(); tv.on(); ((LivingRoomTV)tv).setSource("HDMI ARC"); stick.on(); soundBar.on(); soundBar.setSoundMode("Dolby Atmos"); stick.openApp("Netflix"); stick.selectContent(movieName); ((LivingRoomLight)livingRoomLight).dim(); soundBar.volume(20); stick.play(); } public void prepareFood(List<String> pizzaNames) { kitchenLight.on(); // normally refrigerator runs always. so no need to turn on. refrigerator.partyMode(); // for fast cooling microwave.on(); microwave.setOnPreHeat(200, 5); microwave.grillOn(); grill.on(); maker.on(); pizzaNames.forEach(pizzaName -> microwave.bake(pizzaName, 400, 10)); } public void stopMovie() { stick.closeApp(); stick.off(); soundBar.off(); tv.off(); ((LivingRoomLight)livingRoomLight).bright(); fan.off(); } public void closeKitchen() { refrigerator.normalMode(); grill.off(); maker.off(); microwave.off(); } }
这是我们要处理的 立面方法
设置家庭娱乐系统以播放电影。 为家人和朋友准备食物。 电影完成后,关闭家庭娱乐系统。 关闭厨房电器后,我们的家庭聚会就会发布。 现在,是时候编写我们的Main 应用程序来执行HomeFacade 并测试输出了:
package org.trishinfotech.facade; import java.util.Arrays; public class Main { public static void main(String[] args) { HomeFacade home = new HomeFacade(); System.out.println("Weekend: Enjoying with friends and family at home..."); System.out.println("-----------------------------------------------------------------"); System.out.println("Setting up movie..."); home.playMovieOnNetflix("Spider-Man: Far From Home"); System.out.println("-----------------------------------------------------------------"); System.out.println("Preparing food..."); home.prepareFood(Arrays.asList("Napoletana Pizza", "Margherita Pizza", "Marinara Pizza", "Chicago-Style Deep Dish Pizza")); System.out.println("-----------------------------------------------------------------"); System.out.println("Enjoy Movie with Meal and Drink..."); System.out.println("Movie Completed."); System.out.println("-----------------------------------------------------------------"); System.out.println("Stopping Movie..."); home.stopMovie(); System.out.println("-----------------------------------------------------------------"); System.out.println("Closing Kitchen..."); home.closeKitchen(); System.out.println("-----------------------------------------------------------------"); System.out.println("Done!"); } }
下面是程序的输出:
Weekend: Enjoying with friends and family at home... ----------------------------------------------------------------- Setting up movie... Turning On 'LivingRoomFan' Encreasing Speed of 'LivingRoomFan' to '2'. Turning On 'LivingRoomLight' Turning On 'LivingRoomTV' Setting Source of 'LivingRoomTV' to 'HDMI ARC'. Turning On 'LivingRoomFireTV4KStick' Turning On 'LivingRoomSoundBar' Setting Sound-Mode of 'LivingRoomSoundBar' to 'Dolby Atmos'. Opening 'Netflix' on 'LivingRoomFireTV4KStick'. Searching 'Spider-Man: Far From Home' on 'Netflix'. Dimming 'LivingRoomLight'. Setting volume of 'LivingRoomSoundBar' to '20'. Playing 'Spider-Man: Far From Home' on 'Netflix'. ----------------------------------------------------------------- Preparing food... Turning On 'KitchenLight' Setting 'Refrigerator' Cooling to 'Party'. Turning On 'Microwave' Setting 'Microwave' on Pre-Heat, temprature '200', time '5' minutes. Turning On 'ElectricGrill' Turning On 'CoffeeMaker' Baking 'Napoletana Pizza' in 'Microwave' for temprature '400', time '10' minutes. Baking 'Margherita Pizza' in 'Microwave' for temprature '400', time '10' minutes. Baking 'Marinara Pizza' in 'Microwave' for temprature '400', time '10' minutes. Baking 'Chicago-Style Deep Dish Pizza' in 'Microwave' for temprature '400', time '10' minutes. ----------------------------------------------------------------- Enjoy Movie with Meal and Drink... Movie Completed. ----------------------------------------------------------------- Stopping Movie... Closing 'Netflix' on 'LivingRoomFireTV4KStick'. Turning Off 'LivingRoomFireTV4KStick' Turning Off 'LivingRoomSoundBar' Turning Off 'LivingRoomTV' Setting brightness of 'LivingRoomLight' to '100'. Turning Off 'LivingRoomFan' ----------------------------------------------------------------- Closing Kitchen... Setting 'Refrigerator' Cooling to 'Normal'. Turning Off 'ElectricGrill' Turning Off 'CoffeeMaker' Turning Off 'Microwave' ----------------------------------------------------------------- Done!
而已!
源代码可以在这里找到:Facade-Design-Pattern-Sample-Code
常见问题解答:
原文链接:http://codingdict.com