技术标签: Design Patterns Java 设计模式
当子系统经过不断的演变,变得异常复杂时,这时候,为了让子系统能够工作,这就要求 客户端对子系统内的各个模块充分了解,才能使各个模块协同工作,达到业务目标。这样无疑增加了客户端的负担。这时候子系统可以为外部定义一个访问的接口,通过接口来完成内部的实现,客户端不需要考虑过多的东西。
举一个例子,某君要开一个公司,他通过了解,得知注册一个公司大概要经过以下几个步骤:
1.到工商部门申请一个公司名称; // commercialDepartment.applyCompanyName()
2.去银行开一个验资账户 ; // bank.createCheckAccount()
3.准备材料,到工商部门拿营业执照; // commercialDepartment.distributeBusinessLicense()
4. 到公安局备案刻章; // policeBureau.distributeSeal()
5. 到质检局办理组织机构代码证; // qualityInspectionBureau.distributeCertificate()
6. 到税务部门办理税务登记 ; // taxBureau.registerTaxBusiness()
7. 到银行开一个基本账户; // bank.createBasicBank()
8.到税务部门做税种鉴定; // taxBureau.appraiseTaxType()
上面的步骤相信大家都会被吓到:实在太麻烦了!开一个公司需要跑这么多个部门,有的部门还得跑多次,还有就是你要了解这个流程的每一步,对每个部门的具体职责要有很详细的了解,这样才能顺利完成。这个给我们一个非常强烈的感觉:政府机构太臃肿,做一件事怎么就这么难呢!!!!(呵呵,相信大家对这个深有体会吧)
上述的这个流程:主要牵涉到政府的以下几个部门:工商部门、银行、公安局、质检局、税务部门;
在代码里有类似下面的逻辑:对申请者而言,他要持有所有部门的引用,并且对部门的功能有较全面的了解,并且知道这些部门怎么协同工作的。这样无疑增加了额申请者的负担。
package com.lou.design.pattern.Facade;
public class Client {
public void applyRunCompany() {
// 持有对各个部门的引用
CommercialDepartment commercialDepartment = new CommercialDepartment();
Bank bank = new Bank();
PoliceBureau policeBureau = new PoliceBureau();
TaxBureau taxBureau = new TaxBureau();
QualityInspectionBureau qualityInspectionBureau = new QualityInspectionBureau();
// 申请开公司
System.out.println("------开始申请开公司........");
commercialDepartment.applyCompanyName(); //1.到工商部门申请一个公司名称;
bank.createCheckAccount(); // 2.去银行开一个验资账户 ; //
commercialDepartment.distributeBusinessLicense(); //3.准备材料,到工商部门拿营业执照;
policeBureau.distributeSeal(); // 4. 到公安局备案刻章;
qualityInspectionBureau.distributeCertificate(); // 5. 到质检局办理组织机构代码证;
taxBureau.registerTaxBusiness(); // 6. 到税务部门办理税务登记 ;
bank.createBasicBank(); // 7. 到银行开一个基本账户;
taxBureau.appraiseTaxType(); //8.到税务部门做税种鉴定;
System.out.println("苍天啊,终于可以开公司了!!!");
}
public static void main(String[] args) {
new Client().applyRunCompany();
}
}
package com.lou.design.pattern.Facade;
public class Department {
}
class CommercialDepartment{
//工商局其他功能 省略
public void applyCompanyName()
{
System.out.println("工商局:申请一个公司名称。");
}
public void distributeBusinessLicense()
{
System.out.println("工商局:发放营业执照。");
}
//工商局其他功能 省略
}
class Bank{
//银行其他功能 省略
public void createCheckAccount()
{
System.out.println("银行:开一个验资账户。");
}
public void createBasicBank()
{
System.out.println("银行: 开一个基本账户。");
}
//银行其他功能 省略
}
class PoliceBureau{
//其他功能 省略
public void distributeSeal()
{
System.out.println("公安局:备案刻章。");
}
//其他功能 省略
}
class QualityInspectionBureau{
//其他功能 省略
public void distributeCertificate(){
System.out.println("质检局:办理组织机构代码证。");
}
//其他功能 省略
}
class TaxBureau{
//其他功能 省略
public void registerTaxBusiness()
{
System.out.println("税务部门:税务登记。");
}
public void appraiseTaxType()
{
System.out.println("税务部门:税种鉴定。");
}
//其他功能 省略
}
程序运行结果:
鉴于这一流程太过繁琐,有不少人跟政府反映,政府觉得,应该要对老百姓简化流程,给老百姓解决办事难的问题,所以开设了一个绿色通道,申请者只需要将相关的材料交给这个绿色通道,就可以办完开公司的手续了!(如下图所示)
像这样,政府对外公布一个绿色通道,只需要通过绿色通道提供的服务即可,不需要自己再到不同的部门去申请各式各样的请求了。
虽然说政府简化了申请者的流程,但是本来应该有的流程还是必不可少的,只不过是政府部门自己内部协调处理了。
以下是以上优化的代码展示:
package com.lou.design.pattern.Facade;
public class GreenChannel {
public static void applyRunCompany() {
// 持有对各个部门的引用
CommercialDepartment commercialDepartment = new CommercialDepartment();
Bank bank = new Bank();
PoliceBureau policeBureau = new PoliceBureau();
TaxBureau taxBureau = new TaxBureau();
QualityInspectionBureau qualityInspectionBureau = new QualityInspectionBureau();
System.out.println("-----------您正在使用政府绿色通道-------------");
commercialDepartment.applyCompanyName(); //1.到工商部门申请一个公司名称;
bank.createCheckAccount(); // 2.去银行开一个验资账户 ; //
commercialDepartment.distributeBusinessLicense(); //3.准备材料,到工商部门拿营业执照;
policeBureau.distributeSeal(); // 4. 到公安局备案刻章;
qualityInspectionBureau.distributeCertificate(); // 5. 到质检局办理组织机构代码证;
taxBureau.registerTaxBusiness(); // 6. 到税务部门办理税务登记 ;
bank.createBasicBank(); // 7. 到银行开一个基本账户;
taxBureau.appraiseTaxType(); //8.到税务部门做税种鉴定;
System.out.println("谢谢您使用政府绿色通道!");
}
}
package com.lou.design.pattern.Facade;
public class Client {
public void applyRunCompany() {
GreenChannel.applyRunCompany();
}
public static void main(String[] args) {
new Client().applyRunCompany();
}
}
一般地, 假设 客户端Client ,和系统内的若干子系统:A,B,C,D…。 现在Client 要完成一项工作,需要A,B,C,D协调完成。
public class Client{
public void doSomething()
{
A a = new A();
B b = new B();
C c = new C();
D d = new D();
A.doMethod1();
B.doMethod2();
C.doMethod3();
D.doMethod4();
// 再做其他的事情
}
}
像上面的Client完成doSomething() 所要需要执行四个子系统A,B,C,D的相关功能。这就要求Client对其子系统内部要相当的熟悉,知道其内部功能结构才可以。这样会增加Client的负担,整个子系统也显得臃肿和混乱。如果有更多的Client 想实现这样的功能,这样的代码还要重复敲多少遍啊。
现在可以为子系统增加一个接口,Client只需要通过这个接口,即可完成doSomething()的功能。
// 将子系统进行封装,给外界提供一个统一的界面接口,不需要Client对子系统要有高要求的了解。
public class Facade{
public void service()
{
A a = new A();
B b = new B();
C c = new C();
D d = new D();
A.doMethod1();
B.doMethod2();
C.doMethod3();
D.doMethod4();
// 再做其他的事情
}
}
//调用子系统提供的门面
public class Client{
public void doSomething()
{
Facade facade = new Facade();
facade.service();//门面提供的方法
}
}
下面是 StarUML 提供的GoF 设计模式的帮助文档,本人做了粗糙的标注,以飨读者。
一、将HololensCamera对象,放到一个空的GameObject下,命名为HololensComponent.如:二、需要更改HololensCamera的位置和旋转角度的时候只需要更改HololensComponent的transform.position和transform.localEulerAngles便可如:GameObject.Find("Hol...
一、为什么要使用Docker?理由很简单,用了的人都说好用。在多系统的分布式项目中,往往传统的部署发包等操作,那是让每个上线的程序员恨的牙痒呀。通常都是通宵奋战,上生产解决各种部署发包问题。个人简单总结一下三点:1.部署简单且灵活,有独立的运行环境,避免了不必要的冲突。2.节省了资源开销3.类似于java, 打包一次各处部署运行。项目迁移灵活便捷。二、什么是docker呢?在讲之前,先来说说什么时容器?什么时虚拟机?看下图:简单解释一下,图左为容器,图右为虚拟机。Docker 属于 L
350.两个数组的交集II描述 给定两个数组,写一个方法来计算它们的交集。例如 给定 nums1 = [1, 2, 2, 1], nums2 = [2, 2], 返回 [2, 2].注意 输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。 我们可以不考虑输出结果的顺序。跟进 如果给定的数组已经排好序呢?你将如何优化你...
shared_from_this是基类enable_shared_shared_from_this的一个方法,允许继承类获取一个只想自身的shared_ptr智能指针,这个智能指针与已有的shared_ptr共享所有权。具体的使用方法如下#include<memory>#include<iostream>class A : public std::enable_shared_from_this<A>{ public: A(){ std::cou
JS中是没有块级作用域作用域这个概念,为实现块级作用域可通过闭包的形式实现,下面通过一个例子来说一下JS中的块级作用域。function outputName(count){ for (var i = 0; i <count; i++) { console.log(i); } } cons
有很多Web程序中第一次登录后,在一定时间内(如2个小时)再次访问同一个Web程序时就无需再次登录,而是直接进入程序的主界面(仅限于本机)。实现这个功能关键就是服务端要识别客户的身份。而用Cookie是最简单的身从验证。如果用户第一次登录,可以将用户名作为Cookie写到本地,代码如下:Cookie cookie = new Cookie("user", user);coo
首先在这里我很庆幸,终于又解决一个bug,真是bug缠身啊。希望大家相互讨论————菜菜的程序员第一点:先从实体类开始吧,今天要做一个项目,因为查询需要很多字段,但是数据库中没有,这些字段。所以想法有点,扩展原来的实体类。roomQueryVopackage com.hotelsystem.pojo.vo;import com.hotelsystem.pojo.Room;//包装类:...
iOS 开发 进阶 博客http://www.jianshu.com/p/c47c24ab1e76转载于:https://www.cnblogs.com/Ghosgt/p/7650544.html
Haar AdaBoost 车辆检测
1.安装插件gulp-clean-cssnpm install gulp-clean-css --save-dev2.配置gulpfile.jsvar gulp = require("gulp");var cssmin = require('gulp-clean-css');//压缩cssgulp.task('testCssmin', function () { gulp.src('Weba...
知识补充:Core文件作用、设置及用法浅析Linux下core文件我们可以使用strings命令查看字符串内容strings命令打印文件中可打印的字符每隔四个小写字母就可以看到一个大写字母,刚好是ALEXCTF 照着这个规律找下去,得到flag :ALEXCTF{K33P_7H3_g00D_w0rk_up}str='cvqAeqacLtqazEigwiXobxrCrtuiTzahfFreqc{bnjrKwgk83kgd43j85ePgb_e_rwqr7fvbmHjklo3tews_hmko
Toolbar是由AndroidX库提供的,它的强大之处在于,它不仅继承了ActionBar的所有功能,并且灵活度很高,可以配合其他控件完成一些Material Design的效果。Theme.MaterialComponents.DayNight.NoActionBar:表示浅色主题,它会将界面的主题颜色设成浅色,陪衬颜色设为深色。Theme.MaterialComponents.NoActionBar:表示深色主题,它会将界面的主题颜色设成深色,陪衬颜色设为浅色。在themes的两个xml文件中,