设计模式入门(策略模式)

【0】README
0.1)本文部分文字描述转自 “head first 设计模式”,旨在学习 设计模式入门(策略模式) 的基础知识;
0.2)本文章节4和5的source code,参见 设计模式——策略模式源代码

【1】看个荔枝(从模拟鸭子应用说起)

1.1)我们让鸭子飞起来:
method1)利用继承实现:在Duck中加入 fly() 方法,不过并不是所有的鸭子都会飞,比如橡皮鸭子;(干货——继承所出现的问题)
Attention)利用继承来提供Duck的行为,这会导致下列哪些缺点(defects):
d1)代码在多个子类中重复;
d2)运行时的行为不容易改变;
d3)很难知道所有鸭子的全部行为;
d4)改变会牵一发而动全身,造成其他鸭子不想要的改变;
method2)利用接口实现:这将导致一个问题,虽然Flyable 和 Quackable 可以解决问题,但是代码不能复用;(干货——接口实现所出现的问题)

【2】设计原则
2.1)原则1:找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起;
2.2)原则2:针对接口编程,而不是针对实现编程;
2.3)针对接口编程的真正意思是:针对超类编程,可以更明确地说成“变量的声明类型应该是超类型,可以是一个抽象类或一个接口,只要是具体实现此超类的子类,都可以指定给这个变量”;(干货——针对接口编程)

【3】solution——如何实现鸭子的行为(我们应该在鸭子类中包含设定行为的方法,这样就可以在运行时动态地改变绿头鸭的行为。)
3.1)我们有两个接口——FlyBehavior 和 QuackBehavior;

3.2)对以上设计的分析(Analysis):
A1)这样一来,可以让飞行和呱呱叫(quack)的动作被其他对象复用,因为这些行为与鸭子类无关了;
A2)而我们新增一些行为,不会影响到既有的行为类,也不会影响 使用这些行为的 具体类,如鸭子类;

【4】整合鸭子的行为
4.1)关键在于: 鸭子现在会将飞行和呱呱叫的动作委托别人进行处理,而不是使用定义在Duck类内的 呱呱叫和飞行方法;
4.2)整合后的代码如下:



【5】动态设定行为
5.1)我们想通过在鸭子子类中通过“设定方法”来设定鸭子的行为,而不是在鸭子的构造器内实例化;
step1)在Duck类中,加入两个新方法: setFlyBehavior 和 setQuackBehavior;
package com.designpattern.chapter0;public abstract class Duck {FlyBehavior flyBehavior;QuackBehavior quackBehavior;public Duck(){}public void setFlyBehavior(FlyBehavior fb){flyBehavior = fb;}public void setQuackBehavior(QuackBehavior qb){quackBehavior = qb;}public abstract void display();public void performFly(){flyBehavior.fly();}public void performQuack(){quackBehavior.quack();}public void swim(){System.out.println("i am swiming!");}}
step2)制造一个新的鸭子类型:模型鸭(ModelDuck.java)
package com.designpattern.chapter0;public class ModelDuck extends Duck{public ModelDuck(){quackBehavior = new Quack();flyBehavior = new FlyWithWings();}@Overridepublic void display() {System.out.println("i am a model duck!");}
}
step3)建立一个新的 FlyBehavior 类型(FlyRocketPowered.java)
package com.designpattern.chapter0;public class FlyRocketPowered  implements FlyBehavior{@Overridepublic void fly() {System.out.println("i am flying with rocket power!");}
}
step4)改变测试类,加入模型鸭,并使模型鸭具有火箭动力;
package com.designpattern.chapter0;public class ModelDuckSimulator {public static void main(String[] args) {Duck mallard = new MallardDuck();mallard.performQuack();mallard.performFly();Duck modelDuck = new ModelDuck();modelDuck.performFly();modelDuck.setFlyBehavior(new FlyRocketPowered());modelDuck.performFly();}
}
5.2)组合定义:将两个类结合起来使用,这就是组合。这种做法和继承不同的地方在于,鸭子的行为不是继承来的,而是和适当的行为对象组合来的;
5.3)设计原则: 多用组合,少用继承;

【6】封装行为的大局观
6.1)下面是整个重新设计后的类结构,你所期望的一切都有: 鸭子继承Duck,飞行行为实现 FlyBehavior接口,呱呱叫行为实现 QuackBehavior接口;


6.2)我们不再把鸭子的行为说成是 一组行为,而是将其想象成“一族算法”;

6.3)策略模式定义: 策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户;(干货——策略模式定义)

【7】策略模式总结:
7.1)OO原则(rules):
r1)封装变化;
r2)多用组合,少用继承;
r3)针对接口编程,不针对实现编程;

7.2)OO模式(pattern):
策略模式——策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户;



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

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

相关文章

java oca_OCA的Java拼图游戏第3部分

java oca在Java难题的第三部分中,我们将看到变量命名限制方面的惊喜。 如果我向您展示了这一点,那么我相信您不会因为它无法编译而感到惊讶。 静态是保留关键字之一,为什么它应该起作用? public class Puzzler {public static v…

maven安装遇到的坑

一、环境变量设置没有反应 cmd窗口的设置未更新,需重新开启cmd窗口 二、缺失包 默认加载maven的仓库 配置minor导致官方的Maven库下载不了

单件模式(单例模式)

【0】README0.1)本文部分描述转自 “head first 设计模式”, 旨在学习 单件模式(单例模式) 的相关知识 及其应用;【1】单件模式1.0)单件模式的应用背景:有一些对象其实我们只需要一个&#xff0…

java oca_OCA第5部分中的Java难题

java oca在Java Puzzlers系列的第五部分中,我们将看到与X.parseX(String s)方法相关的内容。 您可以看到我们对X.parseX()方法的期望。 public class Puzzler { public static void main(String[] args){ int i Inte…

Java Excel导出

一、Excel依赖包POI &#xff08;1&#xff09;Maven配置<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.7</version></dependency> &#xff08;2&#xff09;jar下载地址http://poi…

junit4和junit5_JUnit5 TestSuite替代

junit4和junit5JUnit4具有TestSuite类来聚合多个测试。 这在JUnit 5中不可用。通常&#xff0c;通过套件中的一堆命名测试进行的测试发现有些糟透了。 但是&#xff0c;如果目标不是测试发现&#xff0c;而是不同测试类之间的资源共享&#xff0c;那么创建一个父对象是有意义的…

Redis入门(一)之安装

一、下载Redis &#xff08;1&#xff09;Window 下载地址&#xff1a;https://github.com/MSOpenTech/redis/releases &#xff08;2&#xff09;Linux 下载地址&#xff1a;http://redis.io/download 二、安装Redis &#xff08;1&#xff09;window版本 A.解压Redis的zi…

mockito参数匹配_Mockito匹配器优先

mockito参数匹配这篇文章是意见。 让我们看一下Mockito中用于在Java中进行测试的verify方法。 示例&#xff1a; verify(myMock).someFunction(123) –期望在模拟ONCE上使用输入123调用someFunction 。 BDDMockito &#xff0c;我更喜欢完整的BDDMockito替代方案&#xff0c…

Redis入门(二)之数据类型

一、Redis 数据类型 Redis支持五种数据类型&#xff1a; &#xff08;1&#xff09;string&#xff08;字符串&#xff09; &#xff08;2&#xff09;hash&#xff08;哈希&#xff09; &#xff08;3&#xff09;list&#xff08;列表&#xff09; &#xff08;4&#x…

关于Object.clone克隆方法的测试

【0】README 0.1&#xff09;本文旨在用源代码测试说明&#xff0c; Object.clone 的 的克隆机制&#xff08;深拷贝 还是 浅拷贝&#xff09; 的问题&#xff1b; 0.2&#xff09;本文还添加了对System.arraycopy本地方法的测试&#xff08;干货——推荐使用该方法进行数组复…

超音速 启动_超音速亚原子图

超音速 启动MicroProfile GraphQL现在包含在刚发布的Quarkus 1.5.0版本中。 现在&#xff0c;您可以使用code.quarkus.io开始使用Quarkus&#xff0c;并包括SmallRye GraphQL Extension 。 这将创建一个具有以下依赖关系的Quarkus启动器应用程序&#xff1a; <dependency…

Java Json解析

一、Json &#xff08;1&#xff09;语法a.名称/值对数据表示b.大括号持有的对象和每个名称后跟“&#xff1a;”&#xff08;冒号&#xff09;&#xff0c;名称/值对的分离&#xff0c;&#xff08;逗号&#xff09;。c.方括号持有数组和值&#xff0c;&#xff08;逗号&#…

flink 卡夫卡_卡夫卡–一次语义学

flink 卡夫卡在分布式环境中&#xff0c;故障是很常见的情况&#xff0c;可以随时发生。 在Kafka环境中&#xff0c;代理可能崩溃&#xff0c;网络故障&#xff0c;处理故障&#xff0c;发布消息时失败或无法使用消息等。这些不同的场景引入了不同类型的数据丢失和重复。 失败…

Word中标题、图表自动编号的方法

转自&#xff1a;http://blog.sciencenet.cn/blog-344887-543229.html一般情况下&#xff0c;Word文档需要为标题提供连续编号&#xff0c;默认的标题样式并没有自动编号的功能&#xff0c;系统默认的标题样式效果如下图&#xff1a;正确设置标题自动编号的方法具体步骤如下&am…

java jsp总结

一、jsp简介 JSP&#xff08;全称Java Server Pages&#xff09;是由 Sun Microsystems 公司倡导和许多公司参与共同创建的一种使软件开发者可以响应客户端请求&#xff0c;而动态生成 HTML、XML 或其他格式文档的Web网页的技术标准。 JSP 技术是以 Java 语言作为脚本语言的&am…

maven 构建增量包_使用Maven进行增量构建

maven 构建增量包这是2020年&#xff0c;如果您要开始任何新的基于Java的项目&#xff0c;那么gradle应该是第一选择&#xff0c;但是由于某些原因&#xff0c;如果您仍然对Maven感兴趣&#xff0c;那么您可能会发现这篇文章很有用。 Maven Java / scala编译器插件对增量编译提…

带Quarkus的Qute模板

Quarkus附带了自己的模板引擎Qute&#xff0c;该引擎已经包含了一组有趣的功能。 在下面的视频中&#xff0c;我将展示基于动作的MVC与JAX-RS的基本用法&#xff0c;该行为将我们的请求转发到HTML模板。 要自己尝试Qute&#xff0c;请查看以下资源&#xff1a; 示例项目 Qut…

Spring的IoC与DI差异

一、IoC IoC&#xff0c;全称为Inversion of Control&#xff0c;即控制反转。 IoC是依赖倒置原则的一种代码设计思想&#xff0c;把创建对象的权利交给框架&#xff0c;是框架的重要特征。其包括依赖注入&#xff08;Dependency Injection&#xff0c;简称DI&#xff09;和依赖…

jvm(3)-垃圾收集器与内存分配策略

【0】README0.1&#xff09;本文部分文字转自&#xff1a;深入理解jvm&#xff0c;旨在学习 垃圾收集器与内存分配策略 的基础知识&#xff1b;【1】垃圾回收概述1&#xff09;GC&#xff08;Garbage Collection&#xff09;需要完成的3件事情&#xff1a;哪些内容需要回收&…

防火墙例外里没有远程桌面_证明没有例外

防火墙例外里没有远程桌面您如何证明虚无的存在&#xff1f; 你应该&#xff1f; 在我编写的某些测试中&#xff0c;尤其是围绕验证或创建空对象的测试中&#xff0c;我真正想写的是这样的&#xff1a; assertThat( ... call some code ... ) .doesntThrow(); 您可以合理地编…