策略设计模式

Posted 外酥里嫩唐僧肉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了策略设计模式相关的知识,希望对你有一定的参考价值。

策略设计模式——我的理解



在软件开发中也常常遇到类似的情况,当实现某一个功能存在多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能,如数据排序策略有冒泡排序、选择排序、插入排序、二叉树排序等。


例如:关于大闸蟹的做法有很多种,我们以清蒸大闸蟹和红烧大闸蟹两种方法为例

策略设计模式——结构图解


图解

注意:==策略模式的重心不是如何实现算法,而是如何组织这些算法,从而让程序结构更加灵活==
结构

策略模式的主要角色如下:

  1. 抽象策略(Strategy)类:

    定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。

  2. 具体策略(Concrete Strategy)类:

    实现了抽象策略定义的接口,提供具体的算法实现。

  3. 环境(Context)类:

    持有一个策略类的引用,最终给客户端调用。

策略设计模式应用——(“大闸蟹”做菜)


结构
  1. 首先,定义一个大闸蟹加工的抽象策略类(CrabCooking),里面包含了一个做菜的抽象方法 CookingMethod();

  2. 然后,定义清蒸大闸蟹(SteamedCrabs)和红烧大闸蟹(BraisedCrabs)的具体策略类,它们实现了抽象策略类中的抽象方法;

  3. 最后,定义一个厨房(Kitchen)环境类,它具有设置和选择做菜策略的方法。

  4. 客户类(Customer),用于模拟点菜,客户类通过厨房类获取做菜策略。

图解

源代码
    /**
* 抽象策略类:大闸蟹加工类
*/
interface CrabCooking{
// 做菜策略
public void CookingMethod();
}
    /**
* 具体策略类:清蒸大闸蟹
*/
class SteamedCrabs extends JLabel implements CrabCooking{
// 实现
@override
public void CookingMethod(){
// 做菜策略,具体实现
}
}

/**
* 具体策略类:红烧大闸蟹
*/
class BraisedCrabs extends JLabel implements CrabCooking{
// 实现
@override
public void CookingMethod(){
// 做菜策略,具体实现
}
}
    /**
* 环境类:厨房
*/
class Kitchen{
// 抽象策略类的引用
private CrabCooking strategy;
// 设置引用
public void setStrategy(CrabCooking strategy){
this.strategy=strategy;
}
// 获取引用
public CrabCooking getStrategy(){
return strategy;
}
// 选择该策略类对应的做菜的策略
public void CookingMethod(){
strategy.CookingMethod();
}
}
// 客户点菜
public class CrabCookingStrategy implements ItemListener{
private JFrame f;
private JRadioButton qz,hs;
private JPanel CenterJP,SouthJP;
private Kitchen cf; //厨房
private CrabCooking qzx,hsx; //大闸蟹加工者
public CrabCookingStrategy(){
f=new JFrame("策略模式在大闸蟹做菜中的应用");
f.setBounds(100,100,500,400);
f.setVisible(true);
f.setResizable(false);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SouthJP=new JPanel();
CenterJP=new JPanel();
f.add("South",SouthJP);
f.add("Center",CenterJP);
qz=new JRadioButton("清蒸大闸蟹");
hs=new JRadioButton("红烧大闸蟹");
qz.addItemListener(this);
hs.addItemListener(this);
ButtonGroup group=new ButtonGroup();
group.add(qz);
group.add(hs);
SouthJP.add(qz);
SouthJP.add(hs);
//---------------------------------
cf=new Kitchen(); //厨房
qzx=new SteamedCrabs(); //清蒸大闸蟹类
hsx=new BraisedCrabs(); //红烧大闸蟹类
}
// 单选按钮的监听事件
public void itemStateChanged(ItemEvent e){
JRadioButton jc=(JRadioButton) e.getSource();
if(jc==qz){
cf.setStrategy(qzx);
cf.CookingMethod(); //清蒸
}
else if(jc==hs){
cf.setStrategy(hsx);
cf.CookingMethod(); //红烧
}
CenterJP.removeAll();
CenterJP.repaint();
CenterJP.add((Component)cf.getStrategy());
f.setVisible(true);
}
// 入口
public static void main(String[] args){
new CrabCookingStrategy();
}
}


以上是关于策略设计模式的主要内容,如果未能解决你的问题,请参考以下文章

Redis实现分布式锁(设计模式应用实战)

使用从循环内的代码片段中提取的函数避免代码冗余/计算开销

用于从 cloudkit 检索单列的代码模式/片段

是否有在单个活动中处理多个片段的 Android 设计模式?

设计模式策略模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

代码片-策略模式+工厂模式