设计模式入门之外观者模式Facade

外观者模式在生活中的示例很多,比如组装电脑。

组装电脑有两种方式:

第一种方式是用户自己去各个零件商买零件,最终把这些零件拼在一起组成电脑;

第二种方式是找一家专门组装电脑的公司,告诉他们你的具体需求,让他们去帮你完成组装电脑的工作。

可见,第一种方式对用户的要求是很高的,需要用户了解各个组件并且需要考虑这些零件的兼容性;而第二种方式中,用户只需要告诉组装公司自己需要干什么,让组装公司去帮助自己完成就好了。第二种方式更加常见一些,原因是这种方式很简单,而且可行。

这这个例子中组装电脑的公司就相当于今天要讨论的外观者

外观者模式的作用可以总结成一句话:为外部系统提供一个界面

外观者模式:为系统外部提供一个界面。外观者让外部系统在不需要了解内部逻辑和组成的情况下实现功能。实现了外部系统与内部系统的封装隔离,松散了系统间的耦合。

案例:代码生成

public class ModelConfig {
	private boolean needGenPresentation = true;
	private boolean needGenBusiness = true;
	private boolean needGenDAO = true;

	public boolean isNeedGenPresentation() {
		return needGenPresentation;
	}

	public void setNeedGenPresentation(boolean needGenPresentation) {
		this.needGenPresentation = needGenPresentation;
	}

	public boolean isNeedGenBusiness() {
		return needGenBusiness;
	}

	public void setNeedGenBusiness(boolean needGenBusiness) {
		this.needNeedGenBusiness = needGenBusiness;
	}

	public boolean isNeedGenDAO() {
		return needGenDAO;
	}

	public void setNeedGenDAO() {
		this.needGenDAO = needGenDAO;
	}
}

public class ConfigManager {
	private static ConfigManager manager = null;
	private static ConfigModel cm = null;

	private ConfigManager() {
		
	}

	public static ConfigManager getInstance() {
		if(manager == null) {
			manager = new ConfigManager();
			cm = new ConfigModel();
		}
		return manager;
	}

	public ConfigModel getConfigData() {
		return cm;
	}
}

public class Presentation {
	public void generate() {
		ConfigModel cm = ConfigManager.getInstance().getConfigData();
		if(cm.isNeedGenPresentation()) {
			System.out.println("正在生成表现成代码");
		}
	}
}

public class Business {
	public void generate() {
		ConfigModel cm = ConfigManager.getInstance().getConfigData();
		if(cm.isNeedGenBusiness()) {
			System.out.println("正在生成业务层代码");
		}
	}
}

public class DAO {
	public void generate() {
		ConfigModel cm = ConfigManager.getInstance().getConfigData();
		if(cm.isNeedGenDAO()) {
			System.out.println("正在生成数据层代码");
		}
	}
}

public class Client {
	public static void main(String[] args) {
		new Presentation().generate();
		new Business().generate();
		new DAO().generate();
	}
}

从客户端的代码看出,客户端需要直接调用各个模块,这样的缺点是,并没有隐藏各个模块的具体实现,而且一旦各个模块有所改变,那客户端的逻辑可能也要收到影响,接下来引入外观者模式。

public class Facade {
	public void function generate() {
		new Presentation().generate();
		new Business().generate();
		new DAO().generate();
	}
}

public class Client {
	public static void main(String[] args) {
		new Facade().generate();
	}
}
这样的话,客户端就只需要直接调用Facade进行操作就可以了,而不需要担心各个模块内部的具体实现。

但是,如果客户端除了要调用组合方法外,有时需要直接调用某个模块该怎么办呢,以下还有更好的方式:

public interface AModuleApi {
	public void a1();//给外部系统调用
	public void a2();//给内部调用
	public void a3();//给内部调用
}

public interface BModuleApi {
	public void b1();//给外部系统调用
	public void b2();//给内部调用
	public void b3();//给内部调用
}

public interface CModuleApi {
	public void c1();//给外部系统调用
	public void c2();//给内部调用
	public void c3();//给内部调用
}

public interface FacadeApi {
	public void a1();//这是各个模块提供给客户端调用的接口
	public void b1();//这是各个模块提供给客户端调用的接口
	public void c1();//这是各个模块提供给客户端调用的接口

	public void test();//这是对外提供的组合接口
}

public class Client {
	public static void main(String[] args) {
		FacadeApi facade = new FacadeImpl();
		facade.a1();
		facade.b1();
		facade.c1();
		facade.test();
	}
}

这样使得系统更加灵活,不光可以让客户端简单的调用组合方法,同时可以满足客户端对内部模块的特殊调用需求。各个模块给出接口,也隐藏了各个模块的具体实现。

外观模式优缺点:

优点:松散耦合,简单易用,更好地划分访问的层次

缺点:容易让人疑惑,到底是调用Facade好呢还是直接调用模块好呢,就好比一个人组装好电脑后,想要扩充内存,到底是找中间公司呢还是自己去买个内存条加上呢。。。




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值