• 设计模式研究(一)实例比较TemplateMethod与Strategy


    一、模式简介

    1、模板方法

     

    用意:准备一个抽象类,将部分逻辑以具体方法以及具体构造子的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。 

     2、策略


    用意:针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换 。

    二、实例比较

    Template Method模式和Strategy模式都可以分离通用的算法和具体的上下文。

    Template Method模式通过继承解决,Strategy通过委托解决。

    分别用以上两个模式来实现冒泡排序。

    1、 Template Method

     public abstract class BubbleSorter
        {
            
    private int operations = 0;
            
    protected int length = 0;
            
    protected int DoSort()
            {
                operations 
    = 0;
                
    if (length < 1)
                    
    return operations;
                
    for (int nextToLast = length - 1; nextToLast >= 0; nextToLast--)
                {
                    
    for (int index = 0; index < nextToLast; index++)
                    {
                        
    if (OutOfOrder(index))
                            Swap(index);
                        operations
    ++;
                    }
                }
                    
    return operations;
            }
            
    protected abstract void Swap(int index);
            
    protected abstract Boolean OutOfOrder(int index);
        }
        
    public class DoubleBubblerSorter:BubbleSorter  
        {
            
    private double[] array = null;
            
    public int Sort(double[] a)
            {
                array 
    = a;
                length 
    = a.Length;
                
    return DoSort();
            }
            
    protected override  void Swap(int index)
            {
                
    double t = array[index];
                array[index] 
    = array[index + 1];
                array[index 
    + 1= t;
            }
            
    protected override Boolean OutOfOrder(int index)
            {
                
    return (array[index] > array[index + 1]);
            }
            
    public void PrintArray()
            {
                
    foreach (var a in array)
                {
                    Console.WriteLine(a);
                }
            }
        }

    通用算法Swap(交换数据),OutOfOrder(是否该交换)被放置在基类中,通过继承,DoubleBubblerSorter实现了针对Double Array的BubblerSorter

    继承关系是强耦合的,BubbleSorter中包含了冒泡排序的算法DoSort。 DoubleBubblerSorter依赖于BubbleSorter。

    运行一下

    DoubleBubblerSorter bs = new DoubleBubblerSorter();
    bs.Sort(new double[] { 12.2342.13.53.84.51.6 });
    bs.PrintArray();

    2、Strategy

     public  class BubbleSorter
        {
            
    private int operations = 0;
            
    private int length = 0;
            
    private SortHandle sorthandle = null;
            
    public BubbleSorter(SortHandle sh)
            {
                sorthandle = sh;
            }

            
    public int Sort(object array)
            {
                sorthandle.SetArray(array);
                length = sorthandle.Length();
                operations = 0;
                
    if (length < 1)
                    
    return operations;
                
    for (int nextToLast = length - 1; nextToLast >= 0; nextToLast--)
                {
                    
    for (int index = 0; index < nextToLast; index++)
                    {
                        
    if (sorthandle.OutOfOrder(index))
                            sorthandle.Swap(index);
                        operations++;
                    }
                }
                
    return operations;
            }

        }
        
    public interface SortHandle
        {
             
    void Swap(int index);
             Boolean OutOfOrder(int index);
             
    int Length();
             
    void SetArray(object array);
        }
        
    public class IntSortHandle : SortHandle
        {
            
    private int[] array = null;
            
    public void Swap(int index)
            {
                
    int t = array[index];
                array[index] = array[index + 1];
                array[index + 1= t;
            }
            
    public  Boolean OutOfOrder(int index)
            {
                
    return (array[index] > array[index + 1]);
            }
            
    public void SetArray(object array)
            {
                
    this.array = (int[])array;
            }
            
    public int Length()
            {
                
    return array.Length;
            }
            
    public void PrintArray()
            {
                
    foreach (var a in array)
                {
                    Console.WriteLine(a);
                }
            }
        }

    上面,扮演Strategy中Context角色的BubbleSorter,包含了冒泡的具体算法。

    IntSortHandle 对BubbleSorter却是一无所知的,它不需要依赖于实现了冒泡排序算法的BubbleSorter。
    在TemplateMethod中,Swap和OutOfOrder的实现依赖于冒泡排序算法(DoubleBubblerSorter依赖于BubbleSorter)。

    而在 Strategy中,IntSortHandle 不需要依赖于BubbleSorter,所以我们可以在其他的排序中使用IntSortHandle

    同样,运行如下:

    IntSortHandle ibs = new IntSortHandle ();
    BubbleSorter2 bs2 = new BubbleSorter2(ibs);
    bs2.Sort(new int[] { 82315 });
    ibs.PrintArray();

    通过上面的例子我们可以看到Strategy模式的好处, 因为Strategy模式完全的遵守DIP原则,所以每个具体实现都可以被多个不同的通用算法操作。

    三、补充说明

    依赖倒置原则(DIP)

    DIP解释:
    1、高层模块不应该依赖于低层模块,二者都应该依赖于抽象。  
    2、抽象不应该依赖于细节。细节应该依赖于抽象。
    DIP中依赖于抽象的把握:
    1、任何变量都不应该持有一个指向具体来的引用。  
    2、任何类都不应该从具体来派生。  
    3、任何方法都不应该覆写它的任何基类中的已经实现的方法。
    我们在项目中的做法:
    每个较高层次都为它所需要的服务声明一个抽象接口,较低的层次实现了这些抽象接口。  
    每个高层类都通过该抽象接口使用下一层,这样高层就不依赖于低层。低层反而依赖于高层中声明的抽象服务接口。

    可以参考我之前写的一篇文章:谈谈我对DI的 理解

    四、参考资料

  • 相关阅读:
    C# 向共享文件夹上传及下载文件
    Generate the Jobs script from msdb Database
    用水晶报表做条码打印
    多语言系统的实现
    用DataBaseMail发图片并茂的邮件
    浅析WINFORM工具条的重用实现
    具有代表性的财务报表--应收帐
    C#实现Combobox自动匹配字符
    动态列报表
    真正通用的SQL分页存储过程
  • 原文地址:https://www.cnblogs.com/tenghoo/p/TemplateMethod_Strategy.html
Copyright © 2020-2023  润新知