1. 外观模式
1.1 介绍
外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。
这种模式涉及到一个单一的类,该类提供了客户端请求的简化方法和对现有系统类方法的委托调用。
1.2 优缺点
优点
- 减少系统相互依赖,减少代码量
- 提高灵活性,
- 提高了安全性
缺点
- 不符合开闭原则,修改门面非常复杂
1.3 使用场景
-
为复杂的模块或子系统提供外界访问的模块。
-
子系统相对独立。
-
3.预防低水平人员带来的风险。
1.4 注意事项
- 在层次化结构中,可以使用外观模式定义系统中每一层的入
2. 案例代码
现在我已经可以自己给娃娃换衣服,或者换娃娃,但是我觉得这样太麻烦了,所以我购买了一台娃娃机,当我告诉它我需要什么样子的娃娃时它就会给我对应的娃娃。
// 布娃娃类
public class Ragdoll {
public String getName(){
return "xx";
};
public static Ragdoll getRagdoll(String ragdollName){
if(ragdollName == "太平公主"){
return new ragdoll_1();
}else if(ragdollName == "白雪公主"){
return new ragdoll_2();
}else if(ragdollName == "铁扇公主"){
return new ragdoll_3();
}
return new ragdoll_1();
}
}
class ragdoll_1 extends Ragdoll{
public String getName(){
return "太平公主";
}
}
class ragdoll_2 extends Ragdoll{
public String getName(){
return "白学公主";
}
}
class ragdoll_3 extends Ragdoll{
public String getName(){
return "铁扇公主";
}
}
public class Skirt {
public String getColor(){
return "xx";
};
public static Skirt getSkirt(String skirtColor){
if(skirtColor == "白色"){
return new WhiteSkirt();
}else if(skirtColor == "红色"){
return new RedSkirt();
}else if(skirtColor == "绿色"){
return new GreenSkirt();
}else if(skirtColor == "黄色"){
return new YellowSkirt();
}
return new RedSkirt();
}
}
class WhiteSkirt extends Skirt{
public String getColor(){
return "白色";
}
}
class RedSkirt extends Skirt{
public String getColor(){
return "红色";
}
}
class GreenSkirt extends Skirt{
public String getColor(){
return "绿色";
}
}
class YellowSkirt extends Skirt{
public String getColor(){
return "黄色";
}
}
public class DecoratorRagdoll {
private Ragdoll ragdoll;
private Skirt skirt;
public void setRagdoll(Ragdoll ragdoll) {
this.ragdoll = ragdoll;
}
public void setSkirt(Skirt skirt) {
this.skirt = skirt;
}
public DecoratorRagdoll() {
this.ragdoll = ragdoll;
this.skirt = skirt;
}
public void work(){
System.out.println("穿着"+this.skirt.getColor()+"裙子的"+this.ragdoll.getName());
}
}
public class Car {
private DecoratorRagdoll ragdoll;
public Car(DecoratorRagdoll ragdoll) {
this.ragdoll = ragdoll;
}
public Car() {
this.ragdoll = ragdoll;
}
public void setRagdoll(DecoratorRagdoll ragdoll) {
this.ragdoll = ragdoll;
}
public void workRagdoll(){
this.ragdoll.work();
}
}
// 负责给我我想要的娃娃
public class CraneMachine {
public DecoratorRagdoll getRagdoll(String ragdollName, String skirtColor){
Ragdoll ragdoll = Ragdoll.getRagdoll(ragdollName);
Skirt skirt = Skirt.getSkirt(skirtColor);
return this.build(ragdoll, skirt);
}
private DecoratorRagdoll build(Ragdoll ragdoll, Skirt skirt){
DecoratorRagdoll decoratorRagdoll = new DecoratorRagdoll();
decoratorRagdoll.setRagdoll(ragdoll);
decoratorRagdoll.setSkirt(skirt);
return decoratorRagdoll;
}
}
/** * 外观模式 * *@Author cly *@Date 2021/08/31 15:19 *@Version 1.0 */
public class Facade {
public static void main(String[] args) {
CraneMachine craneMachine = new CraneMachine();
DecoratorRagdoll ragdoll = craneMachine.getRagdoll("铁扇公主", "白色");
Car car = new Car(ragdoll);
car.workRagdoll();
DecoratorRagdoll ragdoll1 = craneMachine.getRagdoll("白雪公主", "红色");
car.setRagdoll(ragdoll1);
car.workRagdoll();
DecoratorRagdoll ragdoll2 = craneMachine.getRagdoll("太平公主", "黄色");
car.setRagdoll(ragdoll2);
car.workRagdoll();
}
}
3. 源码实现
3.1 Tomcat
Tomcat 中,catalina.jar 中的 RequestFacade 和 ResponseFacade 两个类就使用了外观模式。
servlet-api 中定义了 HttpServlet 抽象类,类中的定义了处理 http get、post、delete… 等请求,返回处理结果,对应需要实现方法 doGet、doPost、doDelete…
这些方法有两个共同的参数:HttpServletRequest、HttpServletResponse
public abstract class HttpServlet extends GenericServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_get_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
} else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
}
}
...
}