随笔 - 1162  文章 - 0  评论 - 16  阅读 - 59万 

一、策略模式

  1、基本介绍

    (1)策略模式(Strategy Pattern)中,定义算法族(策略组),分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户

    (2)这算法体现了几个设计原则:

        第一:把变化的代码从不变的代码中分离出来;

        第二:针对接口编程而不是具体类(定义了策略接口);

        第三:多用组合/聚合,少用继承(客户通过组合方式使用策略);

  2、原理类图

    

 

     说明,从上图可以看到,客户 context 有成员变量 strategy 或者其他的策略接口,至于需要使用到那个策略,我们可以在构造器或者 setter 方法指定。

 

二、策略模式解决鸭子问题

  1、实例要求

    编写程序完成前面的鸭子项目,要求使用策略模式;

  2、思路分析

    策略模式:分别封装行为接口,实现算法族,超类里放行为接口对象,在子类里具体设定行为对象。

    原则就是:分离变化部分,封装接口,基于接口编程各种功能。

    此模式让行为的变化独立于算法的使用者。

    

  3、代码实现

    策略接口:

复制代码
1 public interface FlyBehavior {
2 
3     /**
4      * 子类具体实现
5      */
6     void fly();
7 }
复制代码

 

    接口实现类:

复制代码
 1 public class GoodFlyBehavior implements FlyBehavior{
 2     @Override
 3     public void fly() {
 4         System.out.println("飞翔技术高超~~~");
 5     }
 6 }
 7 -----------------------------------------------
 8 public class BadFlyBehavior implements FlyBehavior{
 9     @Override
10     public void fly() {
11         System.out.println("飞翔技术一般~");
12     }
13 }
14 
15 -----------------------------------------------
16 public class NoFlyBehavior implements FlyBehavior{
17     @Override
18     public void fly() {
19         System.out.println("不会飞翔");
20     }
21 }
复制代码

 

  鸭子抽象类:

复制代码
 1 public abstract class Duck {
 2 
 3     /**
 4      * 属性,策略接口
 5      */
 6     FlyBehavior flyBehavior;
 7     //还会有其他属性 <-> 策略接口
 8 
 9     public Duck() {
10 
11     }
12 
13     /**
14      * 显示鸭子信息
15      */
16     public abstract void display();
17 
18     public void fly() {
19         if (flyBehavior != null) {
20             flyBehavior.fly();
21         }
22     }
23 
24     public void setFlyBehavior(FlyBehavior flyBehavior) {
25         this.flyBehavior = flyBehavior;
26     }
27 }
复制代码

 

  具体实现鸭子类:

复制代码
 1 public class WildDuck extends Duck{
 2 
 3     public WildDuck() {
 4         flyBehavior = new GoodFlyBehavior();
 5     }
 6 
 7     @Override
 8     public void display() {
 9         System.out.println("这是野鸭");
10     }
11 
12 }
13 -------------------------------------------------
14 public class PekingDuck extends Duck{
15 
16     public PekingDuck() {
17         flyBehavior = new BadFlyBehavior();
18     }
19 
20     @Override
21     public void display() {
22         System.out.println("~~~北京鸭~~~");
23     }
24 
25 }
26 -------------------------------------------------
27 public class ToyDuck extends Duck{
28 
29     public ToyDuck() {
30         flyBehavior = new NoFlyBehavior();
31     }
32 
33     @Override
34     public void display() {
35         System.out.println("~~~玩具鸭~~~");
36     }
37 }
复制代码

 

  客户端:

复制代码
 1 public class Client {
 2     public static void main(String[] args) {
 3         WildDuck wildDuck = new WildDuck();
 4         wildDuck.fly();
 5 
 6         ToyDuck toyDuck = new ToyDuck();
 7         toyDuck.fly();
 8 
 9         PekingDuck pekingDuck = new PekingDuck();
10         pekingDuck.fly();
11 
12         //动态改变某个对象的行为
13         pekingDuck.setFlyBehavior(new NoFlyBehavior());
14 
15         System.out.println("北京鸭的实际飞翔能力");
16         pekingDuck.fly();
17     }
18 }
复制代码

 

 

 

posted on   格物致知_Tony  阅读(394)  评论(0编辑  收藏  举报
编辑推荐:
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· 面试官:你是如何进行SQL调优的?
历史上的今天:
2020-03-03 jQuery — 事件对象
点击右上角即可分享
微信分享提示

目录导航