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

目录

一、什么是外观模式?

二、外观模式具有什么优点吗?

三、外观模式具有什么缺点呢?

四、什么时候使用外观模式?

五、代码展示

①、股民炒股代码

②、投资基金代码

③外观模式


思维导图

 

一、什么是外观模式?

为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

Facade:外观,为多个子系统对外提供一个共同的接口

SubSystem:子系统:实现子系统功能,每一个类表示为一个子系统

Client:客户,通过外观访问各个子系统功能

二、外观模式具有什么优点吗?

降低了子系统与客户端之间的耦合度,使得子系统的变化不会影响调用它的客户类;

三、外观模式具有什么缺点呢?

1.不能很好地限制客户使用子系统类,很容易带来未知风险;

2.增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”

四、什么时候使用外观模式?

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

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

③、在维护一个遗留的大型系统时,可能这个系统已经非常难以维护和扩展了,但因为它包含非常重要的功能,新的需求开发必须要依赖于它。


五、代码展示

场景:越来越多的人都在炒股票,行情很火, 但许多人进入这个行业只是盲目跟风,并不是足够了解证券知识,对于这个行业并不熟悉。如果是你自己单独去买股票的话需要了解每支股票具体的细节,如果要买十股的话就需要了解是个,这样非常麻烦。这个时候你就会想如果有一个帮手来帮助你管理股票的话就好了!基金就可以作为你的帮手,它把投资者分散的资金集中起来,交给专业的经理人进行管理,投资于股票、债券、外汇等领域,而基金投资的收益归持有投资者所有,管理机构只是收取一定比例的托管管理费用。你不需要了解股票具体是什么时候买和卖合适,你只需要把钱给基金,基金帮你买了这十股。

①、股民炒股代码

股票类

//股票1
class Stock1
{//卖股票public void Sell(){Console.WriteLine(" 股票1卖出");}//买股票public void Buy(){Console.WriteLine(" 股票1买入");}
}//股票2
class Stock2
{//卖股票public void Sell(){Console.WriteLine(" 股票2卖出");}//买股票public void Buy(){Console.WriteLine(" 股票2买入");}
}// 股票3
class Stock3
{//卖股票public void Sell(){Console.WriteLine(" 股票3卖出");}//买股票public void Buy(){Console.WriteLine(" 股票3买入");}
}//国债1
class NationalDebt1
{//卖股票public void Sell(){Console.WriteLine(" 国债1卖出");}//买股票public void Buy(){Console.WriteLine(" 国债1买入");}
}// 房地产1
class Realty1
{//卖股票public void Sell(){Console.WriteLine(" 房地产1卖出");}//买股票public void Buy(){Console.WriteLine(" 房地产1买入");}
}

客户端

static void Main(string[] args)
{Stock1 gu1 = new Stock1();       //关联关系:Stock1 gu1 =null; gu1 = new Stock1();Stock2 gu2 = new Stock2();Stock3 gu3 = new Stock3();NationalDebt1 nd1 = new NationalDebt1();Realty1 rt1 = new Realty1();gu1.Buy();gu2.Buy();gu3.Buy();nd1.Buy();rt1.Buy();gu1.Sell();gu2.Sell();gu3.Sell();nd1.Sell();rt1.Sell();Console.ReadKey();
}

这样的话用户需要了解股票、国债、房产情况,需要参与这些项目的具体买和卖。耦合性很高。我们可以增加基金类。

②、投资基金代码

基金类

//基金类
class Fund
{//成员变量Stock1 gu1;Stock2 gu2;Stock3 gu3;NationalDebt1 nd1;Realty1 rt1;//基金类,它需要了解所有的股票或其他投资方式的方法或属性,进行组合,以备外界调用//此处同原型模式有异曲同工之处,在实例化本类的同时实例化相应的子类public Fund()              //构造方法{gu1 = new Stock1();         //实例化股票1gu2 = new Stock2();         //实例化股票2gu3 = new Stock3();         //实例化股票3nd1 = new NationalDebt1();  //实例化国债1rt1 = new Realty1();        //实例化房地产1}public void BuyFund()        //买{gu1.Buy();gu2.Buy();gu3.Buy();nd1.Buy();rt1.Buy();}public void SellFund()          //卖{gu1.Sell();gu2.Sell();gu3.Sell();nd1.Sell();rt1.Sell();}
}//股票1
class Stock1
{//卖股票public void Sell(){Console.WriteLine(" 股票1卖出");}//买股票public void Buy(){Console.WriteLine(" 股票1买入");}
}//股票2
class Stock2
{//卖股票public void Sell(){Console.WriteLine(" 股票2卖出");}//买股票public void Buy(){Console.WriteLine(" 股票2买入");}
}//股票3
class Stock3
{//卖股票public void Sell(){Console.WriteLine(" 股票3卖出");}//买股票public void Buy(){Console.WriteLine(" 股票3买入");}
}//国债1
class NationalDebt1
{//卖股票public void Sell(){Console.WriteLine(" 国债1卖出");}//买股票public void Buy(){Console.WriteLine(" 国债1买入");}
}房地产1
class Realty1
{//卖股票public void Sell(){Console.WriteLine(" 房地产1卖出");}//买股票public void Buy(){Console.WriteLine(" 房地产1买入");}
}

客户端

static void Main(string[] args)
{ Fund jijin = new Fund();   //实例化基金类jijin.BuyFund();           //调用买的方法jijin.SellFund();           //调用卖的方法//此时用户不需要了解股票,甚至可以对股票一无所知,买了基金就回家睡觉//一段时间后再赎回就可以大把数钱。Console.ReadKey();          //等待用户按下任意键退出
}

这样写的好处是什么?外部不需要知道基金怎么组合的、具体细节,这样就大大降低应用程序复杂度,提高程序可维护性

与其它模式的联系:

基金类中的构造方法和原型模式很类似,客户端在实例化原型对象的时候,同时实例化具体的原型类

基金类中的买和卖的方法和建造者模式中的指挥者类的思想异曲同工之处,客户端提出要建造一个瘦人类告诉指挥者,指挥者指挥工人建造出小人,最后把建造好的小人展示给客户。

③外观模式

//四个子系统类
class SubSystemOne
{public void MethodOne(){Console.WriteLine("子系统方法一");}
}class SubSystemTwo
{public void MethodTwo(){Console.WriteLine("子系统方法二");}
}class SubSystemThree
{public void MethodThree(){Console.WriteLine("子系统方法三");}
}class SubSystemFour
{public void MethodFour(){Console.WriteLine("子系统方法四");}
}//外观类,他需要了解所有的子系统的方法或属性,进行组合,以备外界调用
class Facade
{SubSystemOne one;SubSystemTwo two;SubSystemThree three;SubSystemFour four;public Facade(){one = new SubSystemOne();two = new SubSystemTwo();three = new SubSystemThree();four = new SubSystemFour();}public void MethodA(){Console.WriteLine("\n方法组A() -----");one.MethodOne();two.MethodTwo();three.MethodThree();four.MethodFour();}public void MethodB(){Console.WriteLine("\n方法组B()----");two.MethodTwo();three.MethodThree();}
} 

涉及到的知识

①、构造方法

又叫构造函数。

目的:对类进行初始化。

特点:与类同名,没有返回值,不需要void,在new时候调用。

所有类都有构造方法,如果你不编码则系统默认生成空的构造方法,若你有定义的构造方法,那么默认的构造方法就会失效了

形式:比方说有一个猫出生下来就叫点点,Cat cat = new Cat("点点");

②、修饰符

public:共有的,所有的类都可以访问,

internal:同一项目的可以访问,类默认是这个

private:私有的,只允许同一类中的成员访问,子类都不可访问,成员默认是这个

protected:保护的,只有子类可以访问

③、字段、属性

字段:程序开发中常见的常量或变量,它是类的一个构成部分,它使得类和结构可以封装数据。默认private,只允许本类可以访问,客户端不可以访问

属性:是一个方法或一对方法。默认public,有get和set两个方法

get访问器返回与声明的属性相同的数据类型,表示的意思是调用时可以得到内部字段的值或引用;

set访问器没有显式设置参数,但它有一个隐式参数,用关键字value表示,它的作用是调用属性时可以给内部的字段或赋值。

为什么要使用get和set?

由于属性中可以包含大量的语句,因此可以对赋予的值进行检查,如果值不安全或者不符合要求,就可以进行提示,这样就可以避免因为给属性设置了错误的值而导致的错误

private int age;
public int Aget
{get{return age;}set{if(value<0 && value>100){Console.WriteLine("输入的不合理!");}else{age =value;}
}

④、封装

每个对象都包含它能进行操作所需要的所有信息,这个特性称为封装,因此对象不必依赖其他对象来完成自己的操作。

有什么好处?

  • 良好的封装能够减少耦合;
  • 类内部的实现可以自由地修改;
  • 类具有清晰的对外接口。

⑤、六大关系

关联(Association):对于两个相对独立的对象,当一个对象的实例与另一个对象的一些特定实例存在固定的对应关系时,这两个对象之间为关联关系。

实现:成员变量

图形:实线+箭头

class Student
{public School school;public School(){}
}clss School
{public School(){}
}

聚合(Aggregation):整体和个体,个体可以脱离整体而独立存在。

实现:成员变量、构造方法的参数

图形:实线+空心菱形

 

⑥、六大原则

迪米特法则

如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。

依赖倒转原则

-高层模块不应该依赖底层模块。两个都应该依赖抽象(接口/抽象类)。

-抽象不应该依赖细节(具体类)。细节应该依赖抽象。

无论主板、CPU、内存、硬盘都是在针对接口设计的。CPU作为主板上一个可移动的、可扩展的部分,在设计主板的时候只需要把接口定义好,内部再复杂我也不让外界知道,而主板只需要预留与CPU阵脚的插槽就可以了。内存、硬盘、显卡都是如此,哪部分坏了直接更换那部分就行了,而不会导致整个主板全部都要换。

 

依赖倒转其实可以说是面向对象设计的标准

开闭原则

多扩展开放,对修改关闭。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/64127.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue3实现日历日期选择(不使用任何插件,纯javaScript实现)

个人项目地址&#xff1a; SubTopH前端开发个人站 &#xff08;自己开发的前端功能和UI组件&#xff0c;一些有趣的小功能&#xff0c;感兴趣的伙伴可以访问&#xff0c;欢迎提出更好的想法&#xff0c;私信沟通&#xff0c;网站属于静态页面&#xff09; SubTopH前端开发个人…

中东 Shopify 如何使用 Bytebase 构建一站式数据库开发工作流

公司简介 Salla 是一家 2016 年成立&#xff0c;位于沙特麦加的自建站电商平台。 作为中东 Shopify&#xff0c;其最大的特点是支持阿拉伯语建站&#xff0c;并且提供更多适应中东地区特点的本地化服务。截止目前&#xff0c;已有 47,000 家店铺入驻 Salla&#xff0c;商品销售…

【前端demo】将二进制数转换为十进制数 原生实现

https://github.com/florinpop17/app-ideas 总结 文章目录 效果JavaScript实现进制转换原生代码遇到的问题 效果 二进制转换为十进制若输入为空或不是二进制&#xff0c;提示清空 https://codepen.io/karshey/pen/dywXZYQ JavaScript实现进制转换 parseInt parseInt(111,…

《Kali渗透基础》15. WEB 渗透

kali渗透 1&#xff1a;WEB 技术1.1&#xff1a;WEB 攻击面1.2&#xff1a;HTTP 协议基础1.3&#xff1a;AJAX1.4&#xff1a;WEB Service 2&#xff1a;扫描工具2.1&#xff1a;HTTrack2.2&#xff1a;Nikto2.3&#xff1a;Skipfish2.4&#xff1a;Arachni2.5&#xff1a;OWAS…

前端面试必备 | uni-app 篇(P1-15)

文章目录 1. 请简述一下uni-app的定义和特点。2. uni-app兼容哪些前端框架&#xff1f;请列举几个。3. 请简述一下uni-app的跨平台工作原理。4. 什么是条件编译&#xff1f;在uni-app中如何实现条件编译&#xff1f;5. uni-app中的页面生命周期有哪些&#xff1f;请简要介绍。6…

UG\NX CAM二次开发 插入工序 UF_OPER_create

文章作者:代工 来源网站:NX CAM二次开发专栏 简介: UG\NX CAM二次开发 插入工序 UF_OPER_create 效果: 代码: void MyClass::do_it() {tag_t setup_tag=NULL_TAG;UF_SETUP_ask_setup(&setup_tag);if (setup_tag==NULL_TAG){uc1601("请先初始化加工环境…

【计算机网络】OSI 七层网络参考模型

OSI&#xff08;Open Systems Interconnection&#xff09;七层网络参考模型是一种用于描述计算机网络通信的框架&#xff0c;将网络通信划分为七个不同的层次&#xff0c;每个层次负责不同的功能。 以下为 OSI 七层网络参考模型的简单表格&#xff1a; --------------------…

maven的依赖下载不下来的几种解决方法

前言 每次部署测试环境&#xff0c;从代码库拉取代码&#xff0c;都会出现缺少包的情况。然后找开发一通调试&#xff0c;到处拷包。 方案一&#xff1a;pom文件注释/取消注释 注释掉pom.xml里的报红色的依赖&#xff08;同时可以把本地maven库repo里对应的包删除&#xff09;&…

一款不能错过的Git客户端:Fork for Mac,让你的代码管理更便捷

Fork for Mac是一款强大的Git客户端&#xff0c;让用户在Mac电脑上更方便地进行版本控制和代码管理。它具有以下特点&#xff1a; 易用性&#xff1a;Fork for Mac界面简洁明了&#xff0c;操作简单易懂&#xff0c;让用户可以快速上手。功能强大&#xff1a;支持各种Git功能&…

Mac软件删除方法?如何删除不会有残留

Mac电脑如果有太多无用的应用程序&#xff0c;很有可能会拖垮Mac系统的运行速度。因此&#xff0c;卸载电脑中无用的软件是优化Mac系统运行速度的最佳方式之一。Mac卸载应用程序的方式是和Windows有很大的区别&#xff0c;特别对于Mac新用户来说&#xff0c;如何无残留的卸载删…

【Latex】使用技能站:(三)使用 Vscode 配置 LaTeX

使用 Vscode 配置 LaTeX 引言1 安装texlive2 安装vscode2.1 插件安装2.2 配置 3 安装SumatraPdf3.1 vscode配置3.2 配置反向搜索 引言 安装texlive 安装vscode 安装SumatraPdf 1 安装texlive 在线LaTeX编辑器&#xff1a;https://www.overleaf.com TeX Live下载&#xff1a;h…

【LeetCode】《LeetCode 101》第十二章:字符串

文章目录 12.1 字符串比较242 . 有效的字母异位词&#xff08;简单&#xff09;205. 同构字符串&#xff08;简单&#xff09;647. 回文子串&#xff08;中等&#xff09;696 . 计数二进制子串&#xff08;简单&#xff09; 12.2 字符串理解224. 基本计算器&#xff08;困难&am…

Java的23种设计模式

Java的23种设计模式 一、创建型设计模式1.单例模式 singleton1.1.静态属性单例模式1.2 静态属性变种1.3 基础的懒汉模式1.4 线程安全的懒加载单例1.5 线程安全的懒加载 单例-改进1.6 双重检查锁1.7 静态内部类1.8 枚举单例1.9 注册表单例 2.工厂方法模式 factory3.抽象工厂模式…

IE浏览器攻击:MS11-003_IE_CSS_IMPORT

目录 概述 利用过程 漏洞复现 概述 MS11-003_IE_CSS_IMPORT是指Microsoft Security Bulletin MS11-003中的一个安全漏洞&#xff0c;影响Internet Explorer&#xff08;IE&#xff09;浏览器。这个漏洞允许攻击者通过在CSS文件中使用import规则来加载外部CSS文件&#xff0…

51单片机项目(8)——基于51单片机的DS1302时钟系统

本次做的设计&#xff0c;是利用DS1302时钟芯片&#xff0c;做了一个时钟&#xff0c;并且将实时时间通过串口发送到上位机进行显示。系统运行如下&#xff1a;&#xff08;protues文件和相关keil代码会在文章最后给出&#xff01;&#xff01;&#xff01;&#xff09; DS1302…

[ES]二基础 |

一、索引库操作 1、mapping属性 mapping是对索引库中文档的约束&#xff0c;常见的mapping属性包括&#xff1a; 1)type&#xff1a;字段数据类型&#xff0c;常见的简单类型有&#xff1a; ①字符串&#xff1a;text(可分词的文本)、keyword&#xff08;精确值&#xff0c…

【LeetCode每日一题】——274.H指数

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 排序 二【题目难度】 中等 三【题目编号】 274.H指数 四【题目描述】 给你一个整数数组 ci…

Qt无边框青绿色主题

收费产品&#xff0c;学生党、闹眼子党勿扰 收费金额&#xff1a;500元 1 概述 最近因项目需要&#xff0c;写了一个炫酷的青绿色、无边框界面&#xff0c;和3DSMax的界面有点类似。 2 截图 首先看看3DSMax的界面 不知道大家看出来没&#xff0c;这个ui其实很简单&#xff…

ELK安装、部署、调试 (七)kibana的安装与配置

1.介绍 Kibana 是一个基于浏览器的开源可视化工具&#xff0c;主要用于分析大量日志&#xff0c;以折线图、条形图、饼图、热图、区域图、坐标图、仪表、目标、时间等形式。预测或查看输入源的错误或其他重大事件趋势的变化。Kibana 与 Elasticsearch 和 Logstash 同步工作&am…

15年检测生涯转瞬即逝,复旦MBA助力邢国芒实现质量强国梦

日月光华&#xff0c;旦复旦兮&#xff01;复旦MBA如同一个巨大的磁场&#xff0c;吸引了诸多来自五湖四海、各行各业的职场精英。从初入职场的青涩懵懂到如今的独当一面专业干练&#xff0c;他们逐渐成长为职场的中坚力量&#xff0c;在各自领域内发光发热。作为新时代的青年&…