设计模式之外观模式(Facade)

1.初识外观模式

  这次不先说例子了,先看看一看外观模式的定义吧:

外观模式:提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。

  在软件开发系统中,客户程序经常会与复杂系统的内部子系统之间产生耦合,而导致客户程序随着子系统的变化而变化。那么如何简化客户程序与子系统之间的交互接口?如何将复杂系统的内部子系统与客户程序之间的依赖解耦?这就是外观模式的作用了,我们通过一个外观类定义一个高层接口,该接口中包含子系统的中的接口,这样客户端只需要通过外观类访问各种子系统就可以啦。结构图表示如下:

 

 

  看看这个例子:生活中,人们多多少少都玩过股票吧,那么大家知道股票和基金有什么区别吗?股票的风险大,盈利高,但是一般的股民没有专业的知识则盈利的可能性较低。于是有了一批人,开始购买基金,因为基金风险低,盈利又比银行利率可观。那么大家知道这是为什么吗?基金背后是怎么运作的呢?实际上是:我们客户买基金,钱给他们,他们拿着这个钱去买股票,买债券等等来进行钱生钱的活动,相比之下他们有专业的团队,盈利的可能性更大,所以基金就有了存在的意义。对比一下外观模式的定义,是不是发现这和外观模式是极其的吻合呢?基金就是这个外观啊!!看看我们如何完成应用外观模式的代码吧。(例子参考了《大话设计模式》)

 

2.外观模式实现

 外观模式的代码如下: 

复制代码
 1 //股票1类
 2 class Stock1
 3 {
 4 public:
 5     void Sell();
 6     void Buy();
 7 };
 8 //股票2类
 9 class Stock2
10 {
11 public:
12     void Sell();
13     void Buy();
14 };
15 //国债1
16 class NationalDebt1
17 {
18 public:    
19     void Sell();
20     void Buy();
21 };
22 //外观类
23 class FundFacade
24 {
25     Stock1 *stock1;
26     Stock2 *stock2;
27     NationalDebt1 *national_debt1;
28 public:
29     FundFacade()
30     {
31         stock1 = new Stock1();
32         stock2 = new Stock2();
33         national_debt1 = new NationalDebt1();
34     }
35     void BuyMethod1()
36     {
37         stock1->Buy();
38         national_debt1->Buy();
39     }
40     void BuyMethod2()
41     {
42         stock2->Buy();
43         national_debt1->Buy();
44     }
45 };
复制代码

通过外观模式客户端只需要访问FundFacade类中的成员就可以了,并不需要与具体的每个Stock1Stock2和 NationalDebt1 相关联。这大大降低了耦合性,同时也使得系统容易维护,易于扩展。若需要扩展股票类,只需要加入Stock类;若有了新的购买方案,只需要在FundFacade 类中加一个BuyMethod方法。

3.使用外观模式的场合和好处

(1)在设计初期阶段,应该有意识的将不同的两个层分离,比如经典的三层架构,就需要考虑在数据访问层、业务逻辑层和表示层的层与层之间建立外观,这样可以为复杂的子系统提供一个简单的接口,使得耦合性大大的降低。

(2)在开发阶段,子系统往往因为不断的重构演化而变得原来越复杂,大多数的模式使用时也都会产生很多很小的类,这本是好事,但也给外部调用它们的用户程序带来了使用上的困难,增加外观可以提供一个简单的接口,减少它们之间的依赖。

(3)在维护一个遗留的一个大型系统时,可能这个系统已经非常难以维护和扩展了,但是因为它包含非常重要的功能,新的系统开发必须依赖它,这时也可以应用外观模式。可以为新系统开发一个外观类,来提供粗糙和高度复杂的遗留代码的比较清晰、简单的接口,让新系统与外观类对象交互,外观类负责与遗留代码交互所有复杂的工作。这样分两个小组,一个小组开发外观类与老系统的交互,另一个小组只要了解外观类的接口,直接开发新系统调用这些接口就可以了。

### 部署包含Spring Boot、Redis、Nginx和Vue3项目的指南 #### 使用Docker部署综合项目结构 为了成功地使用Docker部署一个由Spring Boot后端、Redis缓存服务、Nginx作为反向代理以及Vue.js前端组成的复杂Web应用程序,通常需要创建多个容器来分别处理各个组件的服务。这可以通过定义`docker-compose.yml`文件实现多容器编排。 对于具体的配置细节,在`docker-compose.yml`中可以指定同服务之间的依赖关系和服务本身的属性,比如暴露的端口号、挂载的数据卷等[^4]。 #### 构建前后端分离的应用架构 - **后端部分**:基于Spring Boot框架开发API接口,并通过Maven或Gradle工具构建可执行JAR包。在对应的Dockerfile中应指明基础镜像(如采用官方OpenJDK镜像),复制打包好的jar文件至目标位置并设置入口点命令启动Java应用;同时利用环境变量传递必要的配置项给应用程序实例,例如数据库连接字符串或者密钥等敏感信息[^3]。 如果遇到类似`ADD failed: file not found in build context or excluded by .dockerignore`这样的错误,则可能是由于`.dockerignore`文件排除了所需的资源或者是当前工作目录下的相对路径正确所引起的。确保项目根目录存在有效的输出制品并且未被忽略规则匹配上是解决问题的关键所在[^2]。 - **前端部分**:以Vue CLI脚手架为基础建立单页面应用(SPA),经过npm run build指令产出静态网页资产放置于特定文件夹内供后续集成调优阶段引用。针对Vue Router的历史模式(History Mode)特性做适配调整时,需配合Nginx服务器设定恰当的位置路由规则以便正确解析URL地址映射到实际存在的HTML文档片段之上[^1]。 ```yaml version: '3' services: backend: image: springboot-app ports: - "8080:8080" environment: SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/mydatabase?useSSL=false&serverTimezone=UTC SPRING_REDIS_HOST: redis depends_on: - db - redis frontend: image: nginx volumes: - ./frontend/dist:/usr/share/nginx/html ports: - "80:80" db: image: mysql/mysql-server:latest environment: MYSQL_ROOT_PASSWORD: jeecg123456 volumes: - db_data:/var/lib/mysql redis: image: redis:alpine volumes: db_data: ``` 上述YAML片断展示了如何组合各独立部件形成统一的整体解决方案。其中特别强调了关于MySQL密码默认值的信息[^5]。 #### 注意事项 确保所有涉及的安全凭证都妥善保管起来,要硬编码进源代码或是公开版本控制系统里面去。另外考虑到生产环境中可能涉及到更复杂的网络策略与安全组规则等因素的影响,建议提前做好充分测试验证再正式上线发布。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值