展览馆网站建设方案书,沃尔玛网上商城中国,wordpress 语言文件夹,绿色为主色的网站一. 外观模式
1. 背景 在现实生活中#xff0c;常常存在办事较复杂的例子#xff0c;如办房产证或注册一家公司#xff0c;有时要同多个部门联系#xff0c;这时要是有一个综合部门能解决一切手续问题就好了。 软件设计也是这样#xff0c;当一个系统的功能越来越强…一. 外观模式
1. 背景 在现实生活中常常存在办事较复杂的例子如办房产证或注册一家公司有时要同多个部门联系这时要是有一个综合部门能解决一切手续问题就好了。 软件设计也是这样当一个系统的功能越来越强子系统会越来越多客户对系统的访问也变得越来越复杂。这时如果系统内部发生改变客户端也要跟着改变这违背了“开闭原则”也违背了“迪米特法则”所以有必要为多个子系统提供一个统一的接口从而降低系统的耦合度这就是外观模式的目标。
2. 定义和特点
(1). 定义 是一种通过为多个复杂的子系统提供一个一致的接口而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口外部应用程序不用关心内部子系统的具体的细节这样会大大降低应用程序的复杂度提高了程序的可维护性。
(2). 优点 A. 降低了子系统与客户端之间的耦合度使得子系统的变化不会影响调用它的客户类。 B. 对客户屏蔽了子系统组件减少了客户处理的对象数目并使得子系统使用起来更加容易。 C. 降低了大型软件系统中的编译依赖性简化了系统在不同平台之间的移植过程因为编译一个子系统不会影响其他的子系统也不会影响外观对象。
(3). 缺点 A. 不能很好地限制客户使用子系统类。 B. 增加新的子系统可能需要修改外观类或客户端的源代码违背了“开闭原则”。
3. 具体实现
(1). 模式结构 A. 外观角色为多个子系统对外提供一个共同的接口。 B. 子系统角色实现系统的部分功能客户可以通过外观角色访问它。 C. 客户端通过一个外观角色访问各个子系统的功能。
结构图如下 (2). 使用场景
见下面代码。
(3). 代码实操
子系统代码 /// summary/// 子业务类1/// /summarypublic class ChildService1{public void MyHandler1(){Console.WriteLine(我正在处理业务1);}}/// summary/// 子业务类2/// /summarypublic class ChildService2{public void MyHandler2(){Console.WriteLine(我正在处理业务2);}}/// summary/// 子业务类3/// /summarypublic class ChildService3{public void MyHandler3(){Console.WriteLine(我正在处理业务3);}}
外观角色 /// summary/// 外观角色/// /summarypublic class FacadeService{private ChildService1 s1 new ChildService1();private ChildService2 s2 new ChildService2();private ChildService3 s3 new ChildService3();public void MyHandler(){s1.MyHandler1();s2.MyHandler2();s3.MyHandler3();}}
测试 {Console.WriteLine(---------------下面是普通调用---------------);ChildService1 s1 new ChildService1();ChildService2 s2 new ChildService2();ChildService3 s3 new ChildService3();s1.MyHandler1();s2.MyHandler2();s3.MyHandler3();Console.WriteLine(---------------下面是外观模式调用---------------);FacadeService f new FacadeService();f.MyHandler();}
运行结果 4. 适用场景分析 (1). 对分层结构系统构建时使用外观模式定义子系统中每层的入口点可以简化子系统之间的依赖关系。 (2). 当一个复杂系统的子系统很多时外观模式可以为系统设计一个简单的接口供外界访问。 (3). 当客户端与多个子系统之间存在很大的联系时引入外观模式可将它们分离从而提高子系统的独立性和可移植性。
更多C后台开发技术点知识内容包括C/CLinuxNginxZeroMQMySQLRedisMongoDBZK流媒体音视频开发Linux内核TCP/IP协程DPDK多个高级知识点。
【文章福利】另外还整理一些C后台开发架构师 相关学习资料面试题教学视频以及学习路线图免费分享有需要的可以点击 C后端学习资料 免费领取 二. 适配器模式
1. 背景 在现实生活中经常出现两个对象因接口不兼容而不能在一起工作的实例这时需要第三者进行适配。例如讲中文的人同讲英文的人对话时需要一个翻译用直流电的笔记本电脑接交流电源时需要一个电源适配器用计算机访问照相机的 SD 内存卡时需要一个读卡器等。 在软件设计中也可能出现需要开发的具有某种业务功能的组件在现有的组件库中已经存在(且不能修改)但它们与当前系统的接口规范不兼容如果重新开发这些组件成本又很高这时用适配器模式能很好地解决这些问题。
2. 定义和特点
(1). 定义 将一个类的方法转换成客户希望的另外一种要求的实现规范使得原本由于接口不兼容而不能一起工作的那些类能一起工作这就是适配器模式。适配器模式分为【类适配器模式】和【对象适配器模式】两种前者类之间的耦合度比后者高且要求程序员了解现有组件库中的相关组件的内部结构所以应用相对较少些。
(2). 优点 A. 客户端通过适配器可以按照系统要求的编程规范透明地调用目标接口。 B. 复用了现存的类程序员不需要修改原有代码而重用现有的适配者类。 C. 将目标类和适配者类解耦解决了目标类和适配者类接口不一致的问题。
(3). 缺点 对类适配器来说更换适配器的实现过程比较复杂。
3. 具体实现
(1). 模式结构 A. 目标接口当前系统业务所要求遵守编程规范的接口它可以是抽象类或接口。 B. 适配者类(被适配的类)第三方提供的新类或系统中已经存在的类它与系统要求的编程规范的目标接口不兼容。 C. 适配器类它是一个转换器通过继承或引用适配者的对象把适配者接口转换成目标接口让客户按目标接口的格式访问适配者。
类适配器图 对象适配器图 (2). 使用场景 系统要求所有的数据库帮助类必须实现ISqlHelp接口面向该接口编程如SQLServerHelp类。 此时第三方提供了一个新的MySql的帮助类(假设是dll不能修改)它的编程规范和ISqlHelp不兼容这个时候就需要引入适配器类使二者能相互兼容。
(3). 代码实操
系统要求的标准开发规范代码 /// summary/// 数据库连接抽象接口/// (代码中统一要求, 对数据库操作都要面向该接口编程)/// /summarypublic interface ISqlHelp{public void Add();public void Del();public void Modify();}/// summary/// SQLServer数据库操作类/// (这是一个样例)/// /summarypublic class SQLServerHelp : ISqlHelp{public void Add(){Console.WriteLine($sqlserver数据库Add成功);}public void Del(){Console.WriteLine($sqlserver数据库Del成功);}public void Modify(){Console.WriteLine($sqlserver数据库Modify成功);}} //1. 项目要求的标准编程模式Console.WriteLine(----------------------------1. 项目要求的标准编程模式---------------------------------);ISqlHelp s1 new SQLServerHelp();s1.Add();s1.Del();s1.Modify();
第三提供的新类, 不满足开发规范 /// summary/// MySQL帮助类(第三方提供,不能修改)/// 没有实现ISqlHelp接口,有自己的一套逻辑./// 但是项目有统一编程要求,要基于ISqlHelp接口编程/// 我们不能修改MySqlHelp内部的逻辑,所以这个时候要通过适配器模式进行适配/// /summarypublic class MySQLHelp{public void AddMySQL(){Console.WriteLine($MySQL数据库Add成功);}public void DelMySQL(){Console.WriteLine($MySQL数据库Del成功);}public void ModifyMySQL(){Console.WriteLine($MySQL数据库Modify成功);}} //2. 第三方给的MySql帮助类,不符合标准模式Console.WriteLine(------------------2. 第三方给的MySql帮助类,不符合标准模式----------------------);MySQLHelp m new MySQLHelp();m.AddMySQL();m.DelMySQL();m.ModifyMySQL();
通过适配器模式兼容新的开发规范 /// summary/// MySQLHelp适配器类1/// (通过继承的方式实现)/// /summarypublic class MySQLHelpAdapter1 : MySQLHelp, ISqlHelp {public void Add(){AddMySQL();}public void Del(){DelMySQL();}public void Modify(){ModifyMySQL();}}/// summary/// MySQLHelp适配器类2/// (通过组合的方式实现,可以属性注入、构造函数注入、方法注入)/// /summarypublic class MySQLHelpAdapter2 : ISqlHelp{public MySQLHelpAdapter2(){}//属性注入,直接写死private MySQLHelp _mySqlHelp new MySQLHelp();/// summary/// 构造函数注入/// 可以改成抽象模式/// /summary/// param namemySqlHelp/parampublic MySQLHelpAdapter2(MySQLHelp mySqlHelp){this._mySqlHelp mySqlHelp;}/// summary/// 方法注入/// 可以改成抽象模式/// /summary/// param namemySqlHelp/parampublic void SetAdapter(MySQLHelp mySqlHelp){this._mySqlHelp mySqlHelp;}public void Add(){_mySqlHelp.AddMySQL();}public void Del(){_mySqlHelp.DelMySQL();}public void Modify(){_mySqlHelp.ModifyMySQL();}} //3.通过适配器模式使用MySQL帮助类,且满足标准编程模式Console.WriteLine(------------------3.1 通过继承模式实现适配器------------------);ISqlHelp s2 new MySQLHelpAdapter1();s2.Add();s2.Del();s2.Modify();Console.WriteLine(------------------3.2 通过组合模式实现适配器------------------);ISqlHelp s3 new MySQLHelpAdapter2();s3.Add();s3.Del();s3.Modify();
适配器运行结果 4. 适用场景分析
(1). 以前开发的系统存在满足新系统功能需求的类但其接口同新系统的接口不一致。
(2). 使用第三方提供的组件但组件接口定义和自己要求的接口定义不同。
三. 模板方法模式
1. 背景 在面向对象程序设计过程中程序员常常会遇到这种情况设计一个系统时知道了算法所需的关键步骤而且确定了这些步骤的执行顺序但某些步骤的具体实现还未知或者说某些步骤的实现与具体的环境相关。 例如去银行办理业务一般要经过以下4个流程取号、排队、办理具体业务、对银行工作人员进行评分等其中取号、排队和对银行工作人员进行评分的业务对每个客户是一样的可以在父类中实现但是办理具体业务却因人而异它可能是存款、取款或者转账等可以延迟到子类中实现。 这样的例子在生活中还有很多例如一个人每天会起床、吃饭、做事、睡觉等其中“做事”的内容每天可能不同。我们把这些规定了流程或格式的实例定义成模板允许使用者根据自己的需求去更新它例如简历模板、论文模板、Word 中模板文件等。
2. 定义和特点
(1). 定义 定义一个操作中的算法骨架而将算法的一些步骤延迟到子类中使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。它是一种类行为型模式。
(2). 优点 A. 它封装了不变部分扩展可变部分。它把认为是不变部分的算法封装到父类中实现而把可变部分算法由子类继承实现便于子类继续扩展。 B. 它在父类中提取了公共的部分代码便于代码复用。 C. 部分方法是由子类实现的因此子类可以通过扩展方式增加相应的功能符合开闭原则。
(3). 缺点 A. 对每个不同的实现都需要定义一个子类这会导致类的个数增加系统更加庞大设计也更加抽象。 B. 父类中的抽象方法由子类实现子类执行的结果会影响父类的结果这导致一种反向的控制结构它提高了代码阅读的难度。
3. 具体实现
(1). 模式结构 A. 抽象类负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。这些方法的定义如下。 ① 模板方法定义了算法的骨架按某种顺序调用其包含的基本方法。 ② 基本方法是整个算法中的一个步骤包含以下几种类型。 抽象方法在抽象类中申明由具体子类实现。 具体方法在抽象类中已经实现在具体子类中可以继承或重写它。 B. 具体子类实现抽象类中所定义的抽象方法。
结构图如下 (2). 使用场景 处理银行业务取号→排队→办业务→评分 除了办业务因人而异外在子类中实现, 其它三步都是固定的在抽象类中实现。
(3). 代码实操
抽象类 /// summary/// 抽象类/// 处理银行业务取号→排队→办业务→评分/// 除了办业务因人而异外, 其它三步都是固定的,在抽象类中实现/// /summarypublic abstract class AbstractHandler{/// summary/// 模板方法/// 里面的步骤是按照固定顺序执行的/// /summarypublic void TemplateMethod(){Handler1();Handler2();Handler3();Handler4();}/// summary/// 具体方法1/// /summarypublic void Handler1(){Console.WriteLine(我是取号业务);}/// summary/// 具体方法2/// /summarypublic void Handler2(){Console.WriteLine(我是排队业务);}/// summary/// 抽象方法3/// 个人业务,因人而异,需要去子类中实现/// /summarypublic abstract void Handler3();/// summary/// 具体方法4/// /summarypublic void Handler4(){Console.WriteLine(我是评分业务);}}
具体子类 /// summary/// 具体子类1/// /summarypublic class ChildHandler1 : AbstractHandler{/// summary/// 重写办个人业务的方法/// /summarypublic override void Handler3(){Console.WriteLine(我来进行理财业务);}}/// summary/// 具体子类2/// /summarypublic class ChildHandler2 : AbstractHandler{/// summary/// 重写办个人业务的方法/// /summarypublic override void Handler3(){Console.WriteLine(我来进行存款业务);}}
测试 {//流程1Console.WriteLine(---------------下面是流程1---------------------);AbstractHandler h1 new ChildHandler1();h1.TemplateMethod();//流程2Console.WriteLine(---------------下面是流程2---------------------);AbstractHandler h2 new ChildHandler2();h2.TemplateMethod();}
运行结果 4. 适用场景分析
(1). 算法的整体步骤很固定但其中个别部分易变时这时候可以使用模板方法模式将容易变的部分抽象出来供子类实现。
(2). 当多个子类存在公共的行为时可以将其提取出来并集中到一个公共父类中以避免代码重复。首先要识别现有代码中的不同之处并且将不同之处分离为新的操作。最后用一个调用这些新的操作的模板方法来替换这些不同的代码。
原文https://www.cnblogs.com/yaopengfei/p/13496730.html