码迷,mamicode.com
首页 > 其他好文 > 详细

设计模式之策略模式参悟

时间:2015-08-27 18:49:10      阅读:160      评论:0      收藏:0      [点我收藏+]

标签:设计模式   生活   策略模式   

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

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

/**
 * 策略模式
 * @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();

在这里使用了委托的形式实现了海鸥的游泳行为。
就像是,人会飞。没错,我们不会飞,但是我们会制造飞机。
我们将飞这件事委托给了飞机。

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

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

设计模式之策略模式参悟

标签:设计模式   生活   策略模式   

原文地址:http://blog.csdn.net/violetic/article/details/48030261

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!