设计模式(一) 策略模式

简介: 最近在看Head First 设计模式这本书,看了一点,第一感觉是简单,通俗易懂,层序渐进,基本上稍微耐心一点都看得懂,那么这本书这么多优点,我写博文是为了什么呢,方便自己以后观看吗?那我还不如看一遍书呢,既然书写的那么好,写给别人看?那还不如推荐别人直接去看书呢。写着系列的博文这也没用,那也没用,那我的出发点是什么呢? 好。我脑袋中的构思是先讲解一下每个模式的基本概念,也就是让你们先知道讲的这个模式的大概意思(尽量跟书上一样简单,就相当于我怎么想的告诉你们,你们可以用来借鉴,如果有更好的讲解方式,可能一起讨论),然后通过找一些实例,来看看这个模式在哪些地方用到了。加深我们的映像,让我们学习

    序言

       最近在看Head First 设计模式这本书,看了一点,第一感觉是简单,通俗易懂,层序渐进,基本上稍微耐心一点都看得懂,那么这本书这么多优点,我写博文是为了什么呢,方便自己以后观看吗?那我还不如看一遍书呢,既然书写的那么好,写给别人看?那还不如推荐别人直接去看书呢。写着系列的博文这也没用,那也没用,那我的出发点是什么呢? 好。我脑袋中的构思是先讲解一下每个模式的基本概念,也就是让你们先知道讲的这个模式的大概意思(尽量跟书上一样简单,就相当于我怎么想的告诉你们,你们可以用来借鉴,如果有更好的讲解方式,可能一起讨论),然后通过找一些实例,来看看这个模式在哪些地方用到了。加深我们的映像,让我们学习设计模式的时候,也能学点别的东西。 这就是我写这一系列博文的目的。

                                                             --WZY

                 策略模式                   

一、准备知识

        多态:父类对象引用子类实例对象,A extends B,A a = new B(); A、B中都有方法run,a.run();此时就是调用B中的run方法。这就是运行时多态,

            为什么叫运行时多态呢?因为在编译的时候,不知道真正的a到底是什么,只知道a是A,在运行时才发现a是B的实例,调用的也就是B中的方法, 

            这样做有什么好处?灵活性、简化性、这种只能通过自己多敲代码才能感觉得到使用多态的好处。。。

        行为组合:通过学习策略模式你就知道了什么是行为组合

二、什么是策略模式?

      在Head First设计模式的书中,用的鸭子的各种行为的例子来说明,看的我头晕眼花,各种鸭子,橡皮鸭都出来了,而且是一步步带领你进入到他所要说的那种思想上去。我感觉对于我这种不喜欢啰嗦麻烦的人来说,是个噩梦,直接看了下面这个图,就理解了什么是策略模式

          一个游戏中有很多角色,有国王、王后、骑士、妖怪等人物,并且每个人物作战的方式也不同,怎么实现呢?

      1、普通方法实现。

        看起来不错啊,哈哈,应有尽有,但是缺点很多,

        1、如果king的战斗方式需要改变呢,变成用枪了,那么我们只好在king类中增加一个GunBehavior方法,然后将fight中改为调用GunBehavior

        2、游戏不止三个骑士,那就来100个骑士,都使用弓箭,但是后面改革了,骑士改为用斧头了,本来妖怪类中就已经实现了斧头的方法,但没办法,我们还有自己在在骑士中实现一遍

        3、这样一来,可扩展性和可复用性都非常差。每个人物中的方法都可能有重复。

       

      2、通过策略者模式怎么实现的呢?看下图。

            1、变化的部分:每个人物使用的战斗行为不一样。所以将战斗的行为都提取出来独立当成一个类

            2、将战斗行为抽取出一个接口来,为的就是使用接口编程的方式。

            3、在Character中申明一个WeaponBehavior变量,也就是为了接口编程后使用多态更方便。

              通过上面三步的改造,现在king使用什么战斗方式,只需要new出来就行了,如果要使用枪,只需要在创建一个GunBehavior的类,然后让king使用

              如果骑士,他们也想用斧头,那么就把骑士中改一行代码,改为用斧头类就好了。

                        其实策略者模式最关键的就是将行为都提取出来封装成独立类,然后让使用者想用什么就new什么。其他使用多态的地方只是设计原则所导致的。

      画图有点失误,没有将weapon.useWeapon()调用。sorry。

策略者模式用到了哪些设计原则?

    1、多用组合、少用继承。这句话中的“组合”的意思就像上面的那些作战行为都封装成一个独立的类,然后组合在一起。继承在这个例子中并没有体现出来。

    2、针对接口编程、而不是针对实现编程。 这个其实就是为了用多态。

    3、找出应用中可能需要变化的地方,把它们独立出来,不要和那些不需要改变的代码混在一起。

策略模式的标准结构图

              

      

三、JDK中使用的策略模式体现

    1、Comparator接口

      记得那个Comparetor这个接口吗,这个就是使用了策略模式写的。在做Comparator和Comparable的比较的时候就说过,实现Comparator是在外部实现compareTo方法,而实现Comparable接口是在内部实现compareTo方法,现在知道为什么Comparator是在外部实现compareTo方法吗,原因就是使用的是策略模式,每个功能/算法类,都必须实现策略接口。然后再需要使用该类的时候,在将其new出来使用.光说没有用,带你看一个非常熟悉的类。String类中就用到了

      首先看一下JDK中实现Comparator接口后扩展了一些什么类

          通过图中可以看到实现该接口的类有很多,但是我们看到一个很熟悉的,java.lang.String下的一个类,说明这个CaseInsensitiveComparator在String中用到了。

    

          打开String的源码,查看了一下,跟我们讲解的一模一样的形式

  

        

      不管这个类的作用是什么,反正我们是看到了熟悉的模式,

        1、CaseInsensitiveComparator实现了Comparator接口

        2、在String中Comparator CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator();

            虽然这个是个常量,但是也没什么大的差别,跟我们自己写的规范是一样的。

    2、ThreadPoolExecutor中的四种拒绝策略

        在JDK中,这个也使用了策略模式,有兴趣的可以去看看,这里我就不带着大家看了。

四、总结

      其实我们平常的代码中,没有那么复杂,只需要将其中变化的部分给抽取出来,达到复用的目的就行了,这种策略模式一般都是在那种比较复杂的情况下,就将其按照上面标准的结构给实现下来。

    

    策略模式的定义:

          1、策略模式定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

              也个定义,通俗的讲,也就是将那些使用的方法风别封装成独立的类,然后将这一类使用接口统一管理起来,让需要使用这些方法的用户能够随时调用他们。上面例子中的战斗行为就相当于定义中的算法一词。只是算了个说法而已。

    缺点:

          1、客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道算法或行为的情况。

          2、由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么这些类的数目就非常多了。

               

相关文章
|
1月前
|
设计模式 算法 Kotlin
Kotlin - 改良设计模式 - 策略模式
Kotlin - 改良设计模式 - 策略模式
47 4
|
3月前
|
设计模式 算法 测试技术
PHP中的设计模式:策略模式的应用与实践
在软件开发的浩瀚海洋中,设计模式如同灯塔,指引着开发者们避开重复造轮子的暗礁,驶向高效、可维护的代码彼岸。今天,我们将聚焦于PHP领域中的一种重要设计模式——策略模式,探讨其原理、应用及最佳实践,揭示如何通过策略模式赋予PHP应用灵活多变的业务逻辑处理能力,让代码之美在策略的变换中熠熠生辉。
|
22天前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
40 1
|
26天前
|
设计模式 前端开发 JavaScript
JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式
本文深入探讨了JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式,结合电商网站案例,展示了设计模式如何提升代码的可维护性、扩展性和可读性,强调了其在前端开发中的重要性。
29 2
|
1月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
45 2
|
2月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
本教程详细讲解Kotlin语法,适合深入学习。快速入门可参考“简洁”系列教程。本文通过游泳运动员的案例,介绍策略模式及其在Kotlin中的改良应用,利用高阶函数简化代码结构,提高灵活性。
38 3
|
2月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
本教程详细讲解Kotlin语法,适合深入学习。快速入门可参考“简洁”系列教程。本文介绍策略模式在Kotlin中的应用,通过游泳运动员的例子,展示如何使用接口和高阶函数实现策略模式,使代码更简洁、灵活。
34 2
|
2月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
66 3
|
2月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
31 3
|
2月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与实践
【10月更文挑战第9天】 策略模式是一种行为设计模式,它允许在运行时选择算法的行为。在PHP开发中,通过使用策略模式,我们可以轻松切换算法或逻辑处理方式而无需修改现有代码结构。本文将深入探讨策略模式的定义、结构以及如何在PHP中实现该模式,并通过实际案例展示其应用价值和优势。
38 1