williambirkin

恭喜发财!

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

意图

将算法封装,使系统可以更换或扩展算法。策略模式的关键是所有子类的目标一致,但是实现的方法不同。

 

使用场合

算法有多种变体可以使用。

多个相似的类仅仅因为行为不同,这时可以将这些类合并并采用策略模式处理这些行为。

一个类的某些行为有过多分支,这时可以将这些行为封装为不同的算法。

希望隐藏算法中采用的数据。

下面是可以使用策略模式的一些具体算法:

采用不同的算法压缩数据。

采用不同的方式对同样的数据绘图,如直方图、折线图或饼分图。

以不同的格式保存数据,如将对象序列化为XML或者二进制格式并保存。

 

结构



Strategy
:定义需要支持的算法的接口,由策略上下文接口调用。

ConcreteStrategy:包含算法的具体策略。

strateinterface:外界用户通过这个接口访问某一个特定的算法,这个接口引用策略对象,并定义一个接口是策略访问其数据。

ContextStrategy的客户。

效果

策略模式使得针对一个问题可以有多个解决方案。

计算库存下限
问题

假设我们在开发一个库存管理软件,目标是通过统计库存变化得出最小的保存库存。
以满足生产前提条件下尽可能地降低库存,达到降低资金占有,降低成本的目的。
但是具体的算法有很多种,不同企业可能会使用不同的算法。
这里我们将采用策略模式来实现程序对多种算法的支持。
结构
采用策略模式计算最小库存的结构如下图

采用车略模式实现最小库存的算法互换和扩展,这里列出3种计算方法,即按照最小输出计算(CompMinStoreByMinOutput),按照最大日输出计算(CompMinStoreByMaxOutputPerDay)和按照平均日输出计算(CompMinStoreByAvgOutput)。


实现

using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.ex324
{
    
public abstract class CompMinStore
    
{
        
public abstract long Comp(StoreContext sc);
    }

}



using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.ex324
{
    
public class StoreContext
    
{
        
private long _minOutputPerDay;
        
private long _maxOutputPerDay;
        
private CompMinStore _cs;

        
public long MinOutputPerDat
        
{
            
get return _minOutputPerDay; }
            
set { _minOutputPerDay = value; }
        }


        
public long MaxOutputPerDay
        
{
            
get return _maxOutputPerDay; }
            
set { _maxOutputPerDay = value; }
        }


        
public CompMinStore CompStrategy
        
{
            
get return _cs; }
            
set { _cs = value; }
        }


        
public long Comp()
        
{
            
return _cs.Comp(this);
        }


    }

}




using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.ex324
{
    
class CompMinStoreByMaxOutputPerDay : CompMinStore
    
{
        
public override long Comp(StoreContext sc)
        
{
            
return (sc.MinOutputPerDat + sc.MinOutputPerDat) / 2 * 10;
        }

    }

}


......


using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.ex324
{
    
public class CompMinStoreByMinOutputPerDay:CompMinStore
    
{
        
public override long Comp(StoreContext sc)
        
{
            
return sc.MaxOutputPerDay * 10;
        }

    }

}




static void Main()
        
{
            StoreContext sc 
= new StoreContext();
            sc.MinOutputPerDat 
= 20;
            sc.MaxOutputPerDay 
= 50;

            CompMinStore s;
            s 
= new CompMinStoreByMaxOutputPerDay();
            sc.CompStrategy 
= s;
            Console.WriteLine(sc.CompStrategy.GetType().ToString() 
+ ":" + sc.Comp());

            s 
= new CompMinStoreByMinOutputPerDay();
            sc.CompStrategy 
= s;
            Console.WriteLine(sc.CompStrategy.GetType().ToString() + ":" + sc.Comp());

            ...... 
            

        }



采用委托技术的策略模式
在.NET平台下,策略模式的一种替代方式或者说变体是采用委托技术。采用委托技术解除了Context与策略类之间的耦合,甚至实现策略的具体类都可以不是相同的父类,只要与策略相关的方法接口相同即可。

using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.ex325
{
    
public delegate void strategy();

    
public class ContextUsingDelegate
    
{
        
public strategy myStrategy;

        
public void ContextInterface()
        
{
            myStrategy();
        }

    }

}



using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern.ex325
{
    
public class StrategyClass
    
{
        
public void ConcreteStrategy()
        
{ }
    }

}



static void Main()
        
{
            StrategyClass sc 
= new StrategyClass();
            ContextUsingDelegate cud 
= new ContextUsingDelegate();
            cud.myStrategy 
= new strategy(sc.ConcreteStrategy);
            cud.ContextInterface();
        }


采用这种方式可以实现策略模式的意图,并且更加灵活,可以减少接口,更有效的复用现有的类。

相关模式
享元模式:可以将策略作为享元,因为策略通常是轻量级对象。
装饰模式:通过为对象增加包装扩展对象的功能,而策略通过修改内部算法改变对象的功能。
posted on 2007-02-09 11:35  williambirkin  阅读(373)  评论(0编辑  收藏  举报