java设计模式外观模式_Java中的外观设计模式

java设计模式外观模式

java设计模式外观模式

在这里,我还有另一篇关于设计模式的文章-Facade Design PatternFacade对象用于通过隐藏复杂系统的复杂性来提供简单接口。

立面设计模式

  • 立面是一种结构设计模式是四个设计模式帮派之一
  • Facade对象用于通过掩盖更复杂的基础系统来提供前端接口。
  • 外观可以提供有限或专用的功能集。 但是,Facade提供的功能主要是客户端应用程序所需的。 因此,它可以根据客户需求提供更多服务。
  • Facade的主要目的是通过提供更简单的界面来处理,以隐藏系统/子系统的复杂性。
  • 当我们必须处理具有许多功能和不同配置的复杂系统/子系统时,使用Facade非常容易。
  • 因此, Facade隐藏了我们应该知道的任何第三方库,系统或子系统的次要和内部细节。
  • 在Java中,有许多功能,例如JDBC,JPA,JAX-RS等,这些功能隐藏了次要细节,并以注释形式或易于配置的方式提供了更简单的界面。
  • 甚至在我们启动系统时运行的计算机系统的POST(开机自检)过程; 是Facade的一个很好的例子。 在控制操作系统之前,它会检查RAM,CPU,HDD和其他连接的外围设备。
  • Facade通过Facade引入了附加的抽象层。 因此,如果子系统发生更改,我们还需要在外观层中进行相应的更改。
立面设计模式
  • 我们可能还会有多个Facade对象,一个对象处理几个子系统,另一个对象处理一些其他子系统。
具有多个子系统的外观设计模式

我希望我们现在清楚什么是Facade ? 为了更清楚地了解它以及在我们的代码中使用Facade,让我们以我们通常在家中使用的家用电器为例。

使用外观设计模式的家用电器应用

为了更容易地理解Facade的用法,我在这里使用示例示例应用程序代码(在Command Design Pattern中使用了示例代码)。 我只做了一些必要的更改,并添加了其他设备和功能的代码,以使示例更加清晰有趣。

该示例还帮助您将Facade与Command Design Pattern进行比较。

设备类代码:

package org.trishinfotech.facade.devices;
 
public abstract class Appliance implements Comparable
   
   
    
     {
 
    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);
        }
    }
}

我在此处添加了“增加”和“减少”速度等操作,以及它的“设备”子类型。

类代码:

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;
    }
}

在这里,我为“声音模式”和“增加”,“减少”,“设置”音量和“静音”等操作添加了代码。

电视课代码:

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");
    }
 
}

微波课程代码:

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;
    }
}

在这里,我定义了诸如“烧烤开/关”,“预加热”和“烘焙”之类的操作。

冰箱类代码:

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;
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
   
   
    
     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 grill of 'Microwave'.
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

翻译自: https://www.javacodegeeks.com/2020/11/facade-design-pattern-in-java.html

java设计模式外观模式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值