java设计模式之外观模式学习笔记
作者:翡青 发布时间:2022-07-02 18:48:06
外观模式: 又称门面模式: 外观Facade为子系统的一组接口提供一个一致界面,使得这组子系统易于使用(通过引入一个新的外观角色降低原系统复杂度,同时降低客户类与子系统的耦合度).
图片来源: 设计模式: 可复用面向对象软件的基础.
实现
案例需求: 租房
有过自己找房租房经历的同学能够体会得到找房是件很痛苦的事, 不光要挨个小区跑而且还要跟(二)房东讨价还价. 于是后来学聪明了, 不再自己挨门挨户的磨嘴皮子, 而是直接找像链家、我爱我家这样的房屋中介, 他们手上握有一定的房源, 我们只需付给他们一笔佣金, 他们便可以代我们跟房东讲价, 而且他们大都很专业, 省时间又省钱. 此时房屋中介就是一个外观Facade, 而房屋的出租户就是子系统SubSystem:
Facade
外观类: 知道哪些子系统负责处理请求, 将客户的请求代理给适当的子系统对象:
public class MediumFacade {
private CuiYuanApartment cuiyuan;
private XiXiApartment xixi;
private XiHuApartment xihu;
public MediumFacade() {
cuiyuan = new CuiYuanApartment("翠苑小区", 900, 1);
xixi = new XiXiApartment("西溪花园", 1200, 1);
xihu = new XiHuApartment("西湖小区", 2600, 1);
}
public void rentingHouse(double price) {
// 价钱合适而且有房可组
if (price >= cuiyuan.getPrice() && cuiyuan.getStatus() != 0) {
System.out.println("预订" + cuiyuan.getLocation());
cuiyuan.setStatus(0);
} else if (price >= xixi.getPrice() && xixi.getStatus() != 0) {
System.out.println("预订" + xixi.getLocation());
xixi.setStatus(0);
} else if (price >= xihu.getPrice() && xihu.getStatus() != 0) {
System.out.println("预订" + xihu.getLocation());
xihu.setStatus(0);
} else {
System.out.println("出价太低/没有房源 ...");
}
}
}
SubSystem
子系统集合: 实现子系统功能, 处理Facade对象指派的任务(注意子系统内没有任何Facade信息,即没有任何Facade对象引用):
/**
* @author jifang
* @since 16/8/23 上午10:12.
*/
public class XiHuApartment {
private String location;
private double price;
private int status;
public XiHuApartment(String location, double price, int status) {
this.location = location;
this.price = price;
this.status = status;
}
public String getLocation() {
return location;
}
public double getPrice() {
return price;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}
class XiXiApartment {
private String location;
private double price;
private int status;
public XiXiApartment(String location, double price, int status) {
this.location = location;
this.price = price;
this.status = status;
}
public String getLocation() {
return location;
}
public double getPrice() {
return price;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}
class CuiYuanApartment {
private String location;
private double price;
private int status;
public CuiYuanApartment(String location, double price, int status) {
this.location = location;
this.price = price;
this.status = status;
}
public String getLocation() {
return location;
}
public double getPrice() {
return price;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}
Client
这样, Client只需跟一个房屋中介联系并给出我们的报价, 他们便会帮我们联系所有符合的房东:
public class Client {
@Test
public void client() {
MediumFacade facade = new MediumFacade();
facade.rentingHouse(800);
}
}
小结
有过面向对象开发经验的同学 即使没有听说过外观模式, 也完全有可能使用过他, 因为他完美的体现了依赖倒转原则和迪米特法则的思想, 是非常常用的模式之一.
使用
首先 在设计初期, 应该有意识的进行层次分离, 比如经典的三层架构, 层与层之间建立Facade, 这样可以为复杂的子系统提供一个简单的接口, 使耦合度大大降低.
其次 在开发阶段, 子系统往往因为不断的重构而变得越来越复杂, 增加Facade可以提供一个简单的接口, 减少模块间依赖.
第三 在维护一个遗留系统时, 可能这个系统已经非常难以维护和扩展了, 但因为它包含非常重要的功能, 新的需求必须依赖它, 此时可以为新系统开发一个Facade, 为设计粗糙或高复杂度的遗留代码提供一个的比较清晰简单的接口, 让新系统与Facade交互, 而Facade与遗留代码交互所有繁杂的工作.
猜你喜欢
- 事件基于委托,可以为任何一种委托类型提供一种发布\订阅机制。使用event关键字将一个委托类型定义为事件。下面通过一个例子介绍事件://事件
- 目录文件下载文件上传 * * 的配置多个 * 的执行顺序异常处理器基于配置的异常处理基于注解的异常处理总结文件下载使用ResponseEn
- [ThreadStatic] static char[]
- 简述增量更新,根据字面理解,就是下载增加的那部分来达到更新的目的,实际就是这个意思。原理用一个旧的Apk安装与一个新的Apk安装包使用 bs
- 方法一:使用AnimatedGif库Nuget安装包:Install-Package AnimatedGif -Version 1.0.5h
- JavaWeb项目部署到服务器详细步骤本地准备在eclipse中将项目打成war文件:鼠标右键要部署到服务器上的项目导出项目数据库文件MyS
- 问题描述在使用mybatis进行开发的时候,由于可以动态拼接sql,这样大大方便了我们。但是也有一定的问题,当我们动态sql拼接的块很多的时
- 发现问题原需求,在一个伸缩列表中,自定义LinearLayout继承LinearLayout动态添加布局。然而实现的时候:一共遍历了30条数
- sftp简介sftp是Secure File Transfer Protocol的缩写,安全文件传送协议。可以为传输文件提供一种安全的网络的
- 查看最新消息要用到类似新浪微博下拉刷新 功能!把最新的消息显示在最上面! 代码如下: PullToRefreshListView类代码 pa
- java执行xshell命令实例import java.io.BufferedReader;import java.io.IOExcepti
- Example官方介绍Query by Example (QBE) is a user-friendly querying techniqu
- 可变数目参数的好处就是在某些情况下可以方便地对参数个数不确定情况的实现,例如计算任意数字的加权和,链接任意字符串为一个字符串等。看下例子:p
- Eclipse 开发java 出现Failed to create the Java Virtual Machine错误解决办法一直用Ecl
- 使用到Process和Runtime两个类,返回值通过Process类的getInputStream()方法获取package ark;im
- 引言从本篇文章开始,我们将介绍 Java AQS 的实现方式,本文先介绍 AQS 的内部数据是如何组织的,后面的文章中再分别介绍 AQS 的
- 介绍使用mybatis时可以使用二级缓存提高查询速度,进而改善用户体验。使用redis做mybatis的二级缓存可是内存可控<如将单独
- 回文数判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。示例 1:输入: 121输出: true示例&
- 最近项目需要实现PDF下载的功能,由于没有这方面的经验,从网上花了很长时间查找了相关的资料。整理之后,发现有几个框架可以实现这个功能。1.
- kafka消费者kafka-console-consumer接收不到数据发送端接收端问题采用内置的zookeeper,发送端发送数据,接收端