策略模式:定义一组算法,将每个算法都封装起来,并且使他们之间可以相互转换,是在接口上面做进一步的处理,体现了面向接口编程的思想
假如现在要设计一个场景,在一片草原上有很多种动物,他们都有吃东西的需求,要怎么用代码来实现这一生态系统。可能大家第一印象想到的就是设计吃东西的接口,然后每种动物分别去实现继承这种接口
public interface Animal {
void eat();
}
狮子吃肉
public class Lion implements Animal {
@Override
public void eat() {
System.out.println("吃肉");
}
}
可是草原上的动物太多了,很多动物可能吃的食物类型是一样的,比如猫科动物都吃肉,家畜(牛,羊)等是吃草,还有卵生动物是杂食,啥都吃,那怎么能实现代码的复用,将同一类型的动物只写一遍实现功能呢?并且如果要给动物添加其他功能,比如说飞行,那Animals里面还能这么写吗?哪些不能飞行的动物怎么办呢?这时候就需要用到策略模式了,如前面所说,策略模式本质上就是对接口做进一步的处理,以简化代码,体现更好的封装
首先是还是要定义吃的接口
public interface Eat {
void eat();
}
接下来我们需要大概区分下所有动物里面有哪些吃的类型
/* 家禽吃草 */
public class Poultry implements Eat{
@Override
public void eat() {
System.out.println("吃草");
}
}
/* 猫科动物吃肉 */
public class Cat implements Eat {
@Override
public void eat() {
System.out.println("吃肉");
}
}
/* 卵生动物杂食:肉和草都吃 */
public class Ovipary implements Eat{
@Override
public void eat() {
System.out.println("吃肉和草");
}
}
接下来就按照不同的动物类型去封装吃的行为
/* 对草原上的动物进行定义 */
public class Animal {
private Eat animal;
public void eat() {
animal.eat();
}
public void setEat(Eat animal) {
this.animal = animal;
}
}
如果现在要写牛的吃的行为
/* 牛 */
public class Cow extends Animal {
public static void main(String[] args) {
Animal cow = new Cow();
/* 牛属于家禽 */
cow.setEat(new Poultry());
cow.eat(); //吃草
}
}
这样一来即对代码进行了封装,同时又能根据不同情况去灵活的变换,这也是策略模式的精髓所在