策略模式:Strategy Pattern,定义了一系列的算法,将每一种算法封装起来并可以相互替换使用,策略模式让算法独立于使用它的客户应用而独立变化。提高灵活性和针对性
就像高人给手下或朋友的一个个锦囊,一个锦囊就是一种算法,发生了什么事情就打开什么锦囊。
public class Test {
public static void main(String[] args) {
}
}
//鸭子类
abstract class Duck {
private String name;
public Duck(String name) {
this.name = name;
}
public void Fly() {
System.out.println("我是鸭子,我飞得老高了" + "我叫:"+name);
}
}
//真鸭子,会飞
class BlackDuck extends Duck {
public BlackDuck(String name) {
super(name);
}
}
//假鸭子,不会飞
class ModelDuck extends Duck {
public ModelDuck(String name) {
super(name);
}
@Override
public void fly() {System.out.println("我是模型假鸭子,我不会飞" + "我叫:"+name);}
}
那么问题来了,我们通过继承的方式,去实现了假鸭子不会飞,但是不会飞的模型鸭子不好销售,我们会生产以各种各样飞行方式的鸭子,这时候通过继承重写相应的方法就显得臃肿了
当对象的某一个行为有着各种不同形式的变化。我们就应该将飞这种方式再次抽象出来,定义出一个借口
interFace Flyable {
public void fly();
}
class FlyImpl implemets Flyable {
public void fly() {
System.out.println("我会飞");
}
}
class NotFlyImpl implemets Flyable {
public void fly() {
System.out.println("我不会飞");
}
}
我们修改一下鸭子类Duck
abstract class Duck {
private String name;
private Flyable fly; //将飞这种行为能力集成到鸭子类
public void setFly(Flyable fly) {this.fly = fly;}
public Duck(String name) {this.name = name}
public void fly() {
System.out.println("我叫:"+name);
fly.fly();
}
}
那么子类就不要再重写方法fly()方法了
public class Test {
public static void main(String[] args) {
Duck black = new BlackDuck("小黑");
black.setFly(new FlyImpl()); //飞这是一种能力,我们根据实际动态的去赋予它特定的能力
black.fly();
Duck model = new ModelDuck("小白");
model.setFly(new NotFlyImlp());
model.fly();
};
}
实际上接口就是抽象出一种行为能力,而在某个类的对象诞生时,才真正赋予它一种能力
体现了OO设计原则:面向接口编程(面向抽象编程,越抽象越适应变化);封装变化; 多用组合,少用继承
可以将一个类看成是各种能力组装起来的。
再粗略的总结品味一下:在一开始,我们将飞作为一种抽象方法写在了Duck类中,那么各种各样的鸭子继承Duck都需要重写fly()方法,我们在实例化对象后,这个对象就有了在类中已经确定好了的飞行能力(会飞or不会飞),那这个对象变懒导致飞行能力不行了或者变强了呢?怎么改变?我们应该将飞行能力抽象成接口,然后实现各种飞行能力,最后通过组合的方式将飞行能力集成到Duck类中,而不是将它看为一种抽象方法,我们在实例化对象后就可以将飞行能力动态的赋予。