策略模式

策略模式(Strategy Pattern)是一种软件设计模式,它定义了一系列算法,并将每个算法封装到一个独立的类中,使它们可以相互替换。策略模式让算法可以在不影响客户端的情况下发生变化,该模式的主要目的是将算法的使用和实现分离开。

举例来说,出门旅行有几种策略:坐飞机,坐火车,骑自行车。我们可以定义一系列旅行方式(策略),使用某个旅行方式时,就实例化某个旅行方式并调用其对应方法。使用策略模式解决上述问题,能够进一步优化代码结构,首先定义一个“旅行方式”接口,把所有的旅行方式组织起来,然后定义一个Context上下文类来管理所有策略。用户选用某种策略时就告诉Context,然后让Context去调用某策略。此时我们可以发现,Context实际上实现了将所有的策略组织起来,由用户选择策略并执行,实现了对行为(策略)的抽象。

策略模式示例

下面代码实现了一个简单的策略模式。

Travel.java

public interface Travel {
    public void travel();
}

TravelByAir.java

public class TravelByAir implements Travel {
    @Override
    public void travel() {
        System.out.println("travel by air");
    }
}

Context.java

public class Context {
    private Travel travel = null;

    public void setTravel(Travel travel) {
        this.travel = travel;
    }

    public void doTravel() {
        this.travel.travel();
    }
}

Main.java

public class Main {
    public static void main(String[] args) {
        Context context = new Context();
        context.setTravel(new TravelByAir());
        context.doTravel();
    }
}

Main函数中,我们选择了一个策略并调用setTravel()传入Context,最后我们调用doTravel()方法执行该策略。

使用策略模式的好处

从上述代码可以看出,策略这种抽象概念是由Context统一管理的,结构上更符合“高内聚”。同时,如果想要扩展策略也十分方便,最简单的写法是使用接口实现一个匿名类即可,我们扩展了功能却不必破坏Context对策略的掌控。

public class Main {
    public static void main(String[] args) {
        Context context = new Context();
        context.setTravel(new Travel() {
            @Override
            public void travel() {
                System.out.println("my travel way");
            }
        });
        context.doTravel();
    }
}

策略模式和简单工厂模式的区别

看了上面代码我们可能要问了,用户不仅要了解Context类还要了解各个Travel的实现类(因为要手动实例化并传入Context),而简单工厂模式却没有这么麻烦,那么为什么需要策略模式?

实际上,简单工厂模式和策略模式侧重的是不同方面,简单工厂模式侧重对象实例化这个过程的管理,而策略模式侧重策略被选择、运行过程中对各个策略的管理。每种设计模式有其侧重点和短板,上面例子只是为了演示什么是策略模式罢了。如果想要进一步优化上面旅行方式的例子,我们完全可以把策略模式和简单工厂模式结合起来,比如用户只对Context传入策略描述,Context调用策略工厂获得一个策略并使用。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。
Copyright © 2017-2024 Gacfox All Rights Reserved.
Build with NextJS | Sitemap