设计模式之策略模式参悟

策略模式的定义:

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

结合日常生活来理解,例如:我们需要一些桌子,但是桌子的颜色,形状等全然不知。

/**
 * 策略模式
 * @author Vio.wang
 *
 * ex: 现在需要一些桌子
 *
 * 桌子的外形 可能为圆形 方形 长方形 等
 * 桌子的颜色 可能为黄色 绿色 灰色 等
 *
 * 桌子的功能 放东西
 *
 */

abstract class BaseTable{

    String shape;
    String color;

    void display() {
        System.out.println("I‘m a "+ color +" table.");
    }

    void placeThing(){
        System.out.println("I can place some things.");
    };

}

/**
 * 红桌子
 * @author Vio.wang
 *
 */
class RedTable extends BaseTable{

    void display() {
        shape = "round";
        color = "red";
        super.display();
    }
}

/**
 * 绿桌子
 * @author Vio.wang
 *
 */
class GreenTable extends BaseTable{

    void display() {
        shape = "round";
        color = "green";
        super.display();
    }

}

这么做,我们就可以很快的按照标准来生产出红桌子,绿桌子等。

利用继承实现桌子特殊功能:

但是,现在我们需要一个可以办公的桌子,但是并不是所有的桌子都可以用来办公。接下来该如何设计呢?

可以在BaseTable中加入 dealBusiness(),不具备办公工作的桌子覆盖dealBusiness(), 什么事也不做。

以上利用继承来实现table的行为有很多的缺点:

1.代码在多个子类中重复

2.运行时的行为不容易改变

3.很难知道桌子具备的全部功能

4.改变会牵一发动全身,造成其他的桌子强行改变

所以继承并不适合解决这种需求,造成的代码无法复用,甚至办公的行为也可能有许多不同的需求。这真是个循环的噩梦。

设计原则:把会变化的部分取出来并封装起来,好让其他的部分不受影响。

优势:代码变化引起的不经意后果变少,系统变得更有弹性。

这样,我们需要讲桌子的办公行为独立出来,重新设计桌子的行为。

设计原则:针对借口编程,而不是针对实现编程。

什么是针对接口编程:

class Dog extends Animal {
    void makeSound() {
        super.makeSound();
        System.out.println("wang~");
    }
}
    Dog dog = new Dog();
        dog.makeSound();

这就是面向实现编程

Animal animal = new Dog();
        animal.makeSound();

这才是面向接口编程,利用多态,我们只需要对象

public static Animal getAnimal(String animal){
        if (animal.equals("dog")) {
            return new Dog();
        }
        if (animal.equals("cat")) {
            return new Animal();
        }
        return null;
    }
getAnimal("dog").makeSound();

我们不关心实际子类型是什么 只关心如何正确的makeSound即可。

我们看看面向接口是如何做的:

例如:鸟类,都是会唱歌,会飞,但是有部分鸟还会游泳。我们如何完成对鸟类的设计呢?


/**
 * 游泳的接口 定义了游泳的行为
 * @author Vio.wang
 *
 */
interface SwimInter {
    void swim();
    void swimNoWay();
}

abstract class Bird {

    SwimInter swimInter;

    abstract void display();
    abstract void sing();

//  在这里我们将游泳的行为委托给swimInter的对象 当swimInter被调用时 也就实现了鸟的游泳行为
    public void performSwim() {
        swimInter.swim();
    };

    /**
     * 可随时改变实现 改变游泳的行为
     * @param inter
     */
    public void setSwimInter(SwimInter inter){
        swimInter = inter;
    }

}

class Seagull extends Bird {

    public Seagull() {
        swimInter = new SwimInter() {

            public void swimNoWay() {

            }

            public void swim() {
                System.out.println("I can swim~~~");
            }
        };
    }

    void display() {
        System.out.println("I‘m a seagull~~~");
    }

    void sing() {
        System.out.println("o~~~");
    }

}
Bird bird = new Seagull();
        bird.performSwim();

        // 可随时改变对SwinInter的实现 从而改变海鸥的游泳行为
        bird.setSwimInter(new SwimInter() {

            public void swimNoWay() {

            }

            public void swim() {
                System.out.println("I can swim so fast~~~");
            }
        });
        bird.performSwim();

在这里使用了委托的形式实现了海鸥的游泳行为。

就像是,人会飞。没错,我们不会飞,但是我们会制造飞机。

我们将飞这件事委托给了飞机。

设计原则:多用组合,少用继承。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-13 12:59:26

设计模式之策略模式参悟的相关文章

设计模式之策略模式(Strategy)摘录

23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象.创建型模式有两个不断出现的主旋律.第一,它们都将关于该系统使用哪些具体的类的信息封装起来.第二,它们隐藏了这些类的实例是如何被创建和放在一起的.整个系统关于这些对象所知道的是由抽象类所定义的接口.因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以

Head First 设计模式之一 策略模式

策略模式 定义 策略模式定义了算法族,分别封装起来,让他们之间可以相互转换,此模式让算法的变化独立于使用算法的客户. 实例 上面的定义看起来说的不太清楚,记定义无意义,理解策略模式还是要看书中的鸭子例子.假设设计一个模拟鸭子的游戏,鸭子的种类有很多,有红头鸭.绿头鸭等等,鸭子可以划水,可以呱嘎叫.在这个模拟游戏的实现上,自然会想到用继承的方法,定义一个鸭子基类,具体的鸭子类型继承自鸭子基类.如下图所示 所有鸭子都会飞.呱呱叫和游泳,这些功能由基类来实现,display函数用来输出鸭子实例的类型,

JavaScript设计模式之策略模式(学习笔记)

在网上搜索“为什么MVC不是一种设计模式呢?”其中有解答:MVC其实是三个经典设计模式的演变:观察者模式(Observer).策略模式(Strategy).组合模式(Composite).所以我今天选择学习策略模式. 策略模式:定义了一系列家族算法,并对每一种算法单独封装起来,让算法之间可以相互替换,独立于使用算法的客户. 通常我并不会记得“牛顿第一定律”的具体内容,所以我也难保证我会对这个定义记得多久……用FE经常见到的东西来举个例子说明一下: $("div").animation(

大话设计模式_策略模式(Java代码)

策略模式:定义算法家族,分别封装,让它们之间可以互相替换,此模式让算法的变化不会影响到使用算法的客户 简单描述:一个父类,多个子类实现具体方法.一个Context类持有父类的引用(使用子类实例化此引用),客户端代码只需要与此Context类交互即可 大话设计模式中的截图: 例子代码: 策略类: 1 package com.longsheng.strategy; 2 3 public abstract class Strategy { 4 5 public abstract double getR

设计模式之策略模式20170720

行为型设计模式之策略模式: 一.含义 策略模式是一种比较简单的模式,也叫做政策模式,其定义如下: 定义一组算法(可抽象出接口),将每个算法都封装起来,并且使它们之间可以互换(定义一个类实现封装与算法切换) 二.代码说明 1.主要有两个角色 1)Context封装角色 它也叫做上下文角色,起承上启下封装作用,屏蔽高层模块对策略,算法的直接访问,封装可能存在的变化. 2)策略角色 该类含有具体的算法 2.在用C实现过程中也是参考这种思想,以压缩,解压算法举例,具体实现如下: 1)策略模式使用场景

<二>读<<大话设计模式>>之策略模式

又和大家见面了,能够坚持写出第二篇文章真不错,好好加油. <<大话设计模式>>讲解策略模式是以商场收银软件程序开头的,那么问题来了,哪家商场收银软件强,开玩笑了.读过上篇文章<<简单工厂模式>>的知道,它有两个缺点:1.客户端依赖两个类,耦合性高:2.如果算法过多则需要写很多类.解决上面问题的就是策略模式了. 策略模式:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户. 商场收银软件:单价*打折算法=售价.

设计模式之策略模式C++实现

策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户. 策略模式UML图如下: 举例: 游泳池中有不同种类的鸭子,有绿头鸭,红头鸭,橡皮鸭,木头鸭等.不同鸭子的特征或行为不同.绿头鸭(MallardDuck)可以叫声是"quack",会飞:橡皮鸭叫声是"queak",不会飞:木头鸭不会叫,也不会飞.利用面向对象原理来设计来泳池中的各种鸭.要求:1.可扩展性好,当有新鸭加入时或鸭的行为有变动时,不用大量改动代码:2.复用性

如何让孩子爱上设计模式 ——14.策略模式(Strategy Pattern)

如何让孩子爱上设计模式 --14.策略模式(Strategy Pattern) 描述性文字 本节讲解的是行为型设计模式中的第一个模式: 策略模式, 这个模式非常简单,也很好理解. 定义一系列的算法,把每个算法封装起来,并使得他们可以相互替换, 让算法独立于使用它的客户而变化. 一般用来替换if-else,个人感觉是面向过程与面向对象思想的 过渡,这里举个简易计算器的栗子,帮助理解~ 普通的if-else/switch计算器 普通的面向过程if-else简易计算器代码如下: 运行结果如下: 这里我

[design-patterns]设计模式之一策略模式

设计模式 从今天开始开启设计模式专栏,我会系统的分析和总结每一个设计模式以及应用场景.那么首先,什么是设计模式呢,作为一个软件开发人员,程序人人都会写,但是写出一款逻辑清晰,扩展性强,可维护的程序就不是那么容易做到了.现实世界的问题复杂多样,如何将显示问题映射到我们编写的程序中本就是困难重重.另一方面,软件开发中一个不变的真理就是"一切都在变化之中",这种变化可能来自于程序本身的复杂度,也可能来自于客户不断变化的需求,这就要求我们在编写程序中一定要考虑变化的因素,将变化的因素抽离出来,