《模式——工程化实现及扩展》(设计模式C# 版)《命令模式 Command》——“自我检验" 参考答案

转自:《模式——工程化实现及扩展》(设计模式C# 版)
http://www.cnblogs.com/callwangxiang/
 

1、              项目中命令模式的“操作”内容经常存在嵌套的要求

例如:排序算法内部往往还涉及交换、移位等操作

请采用本章介绍的泛型委托命名模式定义排序操作,要求它支持针对如下接口的排序算法,并验证之。

 

要求:本示例纯粹为了练习嵌套命令模式的实现方式,请不要使用.NET内置的集合类型排序,也不要通过LINQ执行排序


interface IEntity
{
    
int Id { getset; }
    
int Age { getset; }
}

class Entity : IEntity
{
    
public int Id { getset; }            
    
public int Age { getset; }
}

class EntityWithName : Entity
{
    
public string Name { getset; }
}

 

参考答案

 

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace MarvellousWorks.PracticalPattern.Command.Tests.Exercise
{
    [TestClass]
    
public class HierarchyCommandExerciseFixture
    {
        
interface IEntity
        {
            
int Id { getset; }
            
int Age { getset; }
        }

        
class Entity : IEntity
        {
            
public int Id { getset; }            
            
public int Age { getset; }
        }

        
class EntityWithName : Entity
        {
            
public string Name { getset; }
        }

        
/// <summary>
        
/// 外部排序命令对象抽象定义
        
/// </summary>
        Action<
            IEntity[],                      
//  表示待排序数据
            Action<IEntity[], intint>,    //  表示交换子命令对象抽象定义
            Func<IEntity, IEntity, bool>>   //  表示比较子命令对象抽象定义
            sortHandler;

        IEntity[] testData;

        
/// <summary>
        
/// 准备测试数据
        
/// </summary>
        [TestInitialize]
        
public void Initialize()
        {
            testData 
= new IEntity[]
            {
                
new Entity(){Id = 1, Age = 20},
                
new Entity(){Id=2, Age=18},
                
new Entity(){Id=5, Age=12},
                
new EntityWithName(){Id=4, Age=30},
                
new Entity(){Id=10, Age=13}
            };
        }

        
/// <summary>
        
/// 验证对于ID属性方法的排序
        
/// </summary>
        [TestMethod]
        
public void TestSortById()
        {
            
#region 定义外部排序命令对象

            
//  冒泡算法排序
            sortHandler = (data, swapHandler, compareHandler) =>
                              {
                                  
if ((data == null|| (data.Length == 0)) throw new ArgumentNullException("data");
                                  
if (data.Length == 1return;
                                  
for (var i = 0; i < data.Length - 1; i++)
                                  {
                                      
for (var j = i + 1; j < data.Length; j++)
                                          
if (!compareHandler(data[i], data[j]))
                                              swapHandler(data, i, j);
                                  }
                              };

            
#endregion

            
#region 内部嵌套的命令对象

            Action
<IEntity[], intint>
                swap 
= (data, x, y) =>
                           {
                               var temp 
= data[x];
                               data[x] 
= data[y];
                               data[y] 
= temp;
                           };

            
//  先定义为倒序排列
            Func<IEntity, IEntity, bool> compare = (x, y) => x.Id >= y.Id;

            
#endregion

            
//  验证倒序排列效果
            sortHandler(testData, swap, compare);
            Assert.IsNotNull(testData);
            
for (var i = 0; i < testData.Length - 1; i++)
                Assert.IsTrue(testData[i].Id 
>= testData[i+1].Id);


            
//  修改内部命令对象的定义,采用升序排列
            compare = (x, y) => x.Id <= y.Id;
            
//  重新定义整体的命令对象
            sortHandler(testData, swap, compare);
            
//  验证升序排列效果
            Assert.IsNotNull(testData);
            
for (var i = 0; i < testData.Length - 1; i++)
                Assert.IsTrue(testData[i].Id 
<= testData[i + 1].Id);

        }
    }
}

 

 

2、 请实现一个队列化命令模式示例并验证


 

 参考答案

 

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace MarvellousWorks.PracticalPattern.Command.Tests.Exercise
{
    [TestClass]
    
public class QueuedCommandExerciseFixture
    {
        List
<string> messages = new List<string>{"hello","command""pattern"};
        
        [TestMethod]
        
public void TestQueuedSerializedCommand()
        {
            
//  定义保存命令对象的队列
            
//  命令对象的抽象形式为返回结果为string的空参数方法 Func<string>
            var queue = new Queue<Func<string>>();

            
//  将命令对象入队列
            messages.ForEach(x=>queue.Enqueue(() => x));

            
//  逐个验证出队列后各命令对象是否次序和执行功能正常
            var i = 0;
            
while(queue.Count > 0)
            {
                var command 
= queue.Dequeue();
                Trace.WriteLine(command());
                Assert.AreEqual
<string>(messages[i], command());
                i
++;
            }
            
        }
    }
}

 

 3、 下列示例是Wiki上给出的命令模式示例,请充分利用C#语法特征重写其命令模式部分的执行逻辑,并通过单元测试验证

 

引自:http://en.wikipedia.org/wiki/Command_pattern

 

 

using System;
using System.Diagnostics;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace MarvellousWorks.PracticalPattern.Command.Tests.Exercise
{
    [TestClass]
    
public class RewriteWikiJavaCommandSampleExerciseFixture
    {
        
class Light
        {
            
public void TurnOn(){Trace.WriteLine("the light is on");}
            
public void TurnDown() { Trace.WriteLine("the light is off"); }    
        }

        
class Switch
        {
            
public Action UpCommand { private getset; }
            
public Action DownCommand { private getset; }

            
public void FlipUp() {UpCommand(); }
            
public void FlipDown() { DownCommand(); }
        }

        
/// <summary>
        
/// 验证执行过程
        
/// </summary>
        [TestMethod]
        
public void Test()
        {
            var light 
= new Light();
            var s 
= new Switch()
                        {
                            UpCommand 
= light.TurnOn,
                            DownCommand 
= light.TurnDown
                        };
            s.FlipUp();
            s.FlipDown();
        }
    }
}

 

 

 

 

 

posted @ 2011-05-03 14:09  蜡笔小王  阅读(1511)  评论(0编辑  收藏  举报