策略模式

策略模式:

  策略模式将可变的部分从程序中抽象分离成算法接口,在该接口下分别封装一系列算法实现,并使他们可以相互替换,从而导致客户端程序独立于算法的改变。

  Composition:在类中增加一个私有域,引用另一个已有的类的实例,通过调用引用实例的方法从而获得新的功能,这种设计被称作组合(复合)。

  注:可以研究下Resource对资源的封装,Resource就运用了策略模式

  策略模式设计原则:
    1.找出应用中需要变化的部分,把他们独立出来,不要和那些不需要变化的代码混在一起;
    2.面向接口编程,而不是面向实现编程;
    3.多用组合,少用继承

  这个模式涉及到三个角色:

  ●  环境(Context)角色:持有一个Strategy的引用。

  ●  抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。

  ●  具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。

  举个列子:我们去火车站买火车票,Context就是我们,Strategy就是火车站,Strategy下面的几个具体策略就是有 成人、学生、儿童。火车站会根据这三个策略选一个和你相匹配的,然后收费。我们就取到火车票了。对我们而言,我们的主要目的就是买票,策略不是我们定的,我们都成年了,向买儿童票,人家肯定不卖给你吧。

  这样来看,有一个user类,去火车站买票,火车站就是接口,interface TrainStation,接口里有方法getTicket() ,毕竟我们是主体客户端嘛,所以方法命名为得到火车票。接口下面有几个实现类,分别是成人 学生 儿童。

首先定义火车站接口

package com.zhao.service;

public interface TrainStation {
    public void getTicket();
}

其次是我们的策略:

package com.zhao.service.impl;

import com.zhao.service.TrainStation;

public class Person implements TrainStation{

    @Override
    public void getTicket() {
        System.out.println("买全价票");
    }

}
package com.zhao.service.impl;

import com.zhao.service.TrainStation;

public class Student implements TrainStation{

    @Override
    public void getTicket() {
        System.out.println("买票75折");
    }

}
package com.zhao.service.impl;

import com.zhao.service.TrainStation;

public class Child implements TrainStation{

    @Override
    public void getTicket() {
        System.out.println("半价票");
    }

}

买票是一个行为,但是这个行为有好几种情况,接下来看我们的客户端主体,必须持有TrainStation对象

package com.zhao.client;

import com.zhao.service.TrainStation;

public class User {
    private TrainStation station;

    public User() {

    }

    public User(TrainStation station) {
        this.station = station;
    }
    
    public void ticket(){
        station.getTicket();
    }
}

接下来我们测试下

package com.zhao.client;

import static org.junit.Assert.*;

import org.junit.Test;

import com.zhao.service.impl.Student;

public class UserTest {

    @Test
    public void test() {
        User user=new User(new Student());
        user.ticket();
    }

}

查看输出结果

这就是策略模式,其实我们平时也在用,不过思路没这么清晰。以后写代码也是,多用组合,少用继承,还要面向接口编程。

 

posted @ 2016-04-15 19:51  假寐的我  阅读(137)  评论(0编辑  收藏  举报