本菜也是正在处于学习阶段,对于遗漏与讲错的知识点欢迎批评指教,qq1991861807
策略设计模式的应用场景:当我们公司需要做一套有关鸭子的游戏时(绿头鸭,红头鸭,橡皮鸭等等),鸭子们刚开始可能只会飞行、吱吱叫、游泳。但是随着游戏的不断更新可能会增加新的功能,例如打架,奔跑(喷火也不是不可能)。这时没了解过设计模式的开发者们可能会先创建一个鸭子的抽象类,然后在该类中定义游泳,吱吱叫,飞行的方法,然后子类实现该抽象类,自然而然 子类中就有了游泳,吱吱叫,飞行的方法。但是要知道的是,每个鸭子的叫法不一样,甚至飞行方式也不一样,所以有的时候就需要重写父类中的方法,这样就显得有些麻烦了。但是在后期突然增加了一个喷火的功能,父类中必须新定义一个喷火的方法,所以子类就都能喷火了。但是有的鸭子不会喷火,例如橡皮鸭,所以我不想让这个类有这个方法,但是怎么办呢?
对于这个问题可以用策略模式轻松解决,废话不多说,看代码:
首先定义一个鸭子的抽象类,因为所有的鸭子都会游泳,所以游泳这个功能不变,只把可能出现变化的飞行和吱吱叫定义成接口形式,利用组合添加到Duck类中。
public abstract class Duck {
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public void performQuack() {
quackBehavior.quack();
}
public void performFly() {
flyBehavior.fly();
}
abstract void display();
public void swim() {
System.out.println("鸭子都会游泳,这点毫无疑问!!!");
}
}
public interface QuackBehavior {
void quack();
}
public interface FlyBehavior {
void fly();
}
然后根据各种鸭子详细的动作实现飞行和吱吱叫的接口
public class FlyNoWay implements FlyBehavior{
@Override
public void fly() {
// TODO Auto-generated method stub
System.out.println("我是鸭子,但是我不会飞。。。。");
}
}
public class FlyWithWings implements FlyBehavior{
@Override
public void fly() {
// TODO Auto-generated method stub
System.out.println("鸭子飞起来了!!!!");
}
}
public class MuteQuack implements QuackBehavior{
@Override
public void quack() {
// TODO Auto-generated method stub
System.out.println("我是一只高冷的鸭子,从来不叫。。。。。");
}
}
public class Squeak implements QuackBehavior{
@Override
public void quack() {
// TODO Auto-generated method stub
System.out.println("橡皮鸭子吱吱叫");
}
}
public class Quack implements QuackBehavior{
@Override
public void quack() {
// TODO Auto-generated method stub
System.out.println("鸭子呱呱叫");
}
}
接下来就是定义定义自己的鸭子类了,我定义的是绿头鸭。。。。
public class MallardDuck extends Duck{
public MallardDuck() {
// 实例化父类中的属性
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
}
void display() {
// TODO Auto-generated method stub
System.out.println("我是一只骄傲的绿头鸭。。。。。");
}
}
测试类:
public class TestDuck {
public static void main(String[] args) {
Duck mallard = new MallardDuck();
mallard.display();
mallard.performFly();
mallard.performQuack();
mallard.swim();
}
}
运行结果:
我再定义一个橡皮鸭给大家看看有什么不同之处
public class XiangpiDuck extends Duck{
public XiangpiDuck() {
// TODO Auto-generated constructor stub
quackBehavior = new Squeak();
flyBehavior = new FlyNoWay();
}
@Override
void display() {
// TODO Auto-generated method stub
System.out.println("我是一只驕傲的橡皮鴨子!!!");
}
}
运行结果:
可以看出来,其实只不过是在构造方法实例化父类属性的时候有所不同。
后期我还会写关于观察者模式、工厂模式、装饰器模式等等的相关博客,希望感兴趣的同学可以用csdn关注一波。。。