【发布时间】:2011-08-04 02:45:21
【问题描述】:
在制定好的设计时,您会选择扩展方法还是访问者模式?
哪个更容易设计,什么时候应该在访问者模式上使用扩展方法,反之亦然?
除了语法糖来帮助程序可读性之外,是否有任何充分的正当理由在访问者类上使用扩展方法?
你会如何设计一个包含扩展方法的系统,你会在 UML 图中对它们进行分类吗?
namespace ExtensionMethods
{
public static class MyExtensions
{
public static int WordCount(this String str)
{
return str.Split(new char[] { ' ', '.', '?' },
StringSplitOptions.RemoveEmptyEntries).Length;
}
}
}
我可能有错误的模式,它看起来像上面代码中的访问者模式。所以我认为我的比较成立。
一些代码,我会说扩展方法看起来像访问者模式。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
#region Interfaces
public interface IFred
{
string Data
{
get;
set;
}
string doSomething();
}
public interface IBob
{
string Data
{
get;
set;
}
}
#endregion
#region fred stuff
public partial class Fred : IFred
{
public string doSomething()
{
return this.Data + " is really cool";
}
public string Value()
{
throw new NotImplementedException();
}
}
public partial class Fred
{
public string Data
{
get;
set;
}
}
#endregion
#region bob stuff
public class BobData : IBob
{
public string Data
{
get;
set;
}
}
public class BobData2 : IBob
{
private string pData;
public string Data
{
get
{
return pData + " and then some!";
}
set
{
pData = value;
}
}
}
public class BobVisitor
{
public string dosomething(IBob bobData)
{
Console.WriteLine(bobData.Data);
return "ok";
}
public string dosomethingOnlyToBob(BobData bobData)
{
Console.WriteLine("hello bob version 1");
return "ok";
}
public string dosomethingOnlyToBob2(BobData2 bobData)
{
Console.WriteLine("hello bob version 2");
return "ok";
}
}
#endregion
public static class Visitor
{
public static string visit(this IBob bobObj)
{
Console.WriteLine(bobObj.Data);
return "ok";
}
public static string visit(this IFred fredObj)
{
Console.WriteLine(fredObj.Data);
return "ok";
}
}
class Program
{
static void Main(string[] args)
{
//Another way of abstracting methods from data, using Partial Classes.
var fredObj = new Fred();
fredObj.Data = "fred data";
fredObj.doSomething();
//Create the bob classes version 1 and 2
var bobObj = new BobData();
bobObj.Data = "bob data";
var bob2Obj = new BobData2();
bob2Obj.Data = "bob 2 data";
//using the bobVisitor Class
var bobVisitor = new BobVisitor();
bobVisitor.dosomething(bobObj);
bobVisitor.dosomething(bob2Obj);
bobVisitor.dosomethingOnlyToBob(bobObj);
bobVisitor.dosomethingOnlyToBob2(bob2Obj);
//using the extension methods in the extension class
bobObj.visit();
fredObj.visit();
Console.Read();
}
}
}
【问题讨论】:
-
我认为编写扩展方法和访问者模式本质上是在解决同一个问题。但是使用访问者模式,您可以将逻辑与类完全分离。扩展方法是向类本身添加方法。
-
访问者将数据与方法分开。我认为扩展方法类添加的语法糖混淆了它们的真正含义。我很想称它们为装饰器,但仔细研究后,它们作用于整个班级,检查语法。
-
他们并没有真正在课堂上添加任何东西。只是有点甜美的魔法。
标签: c# design-patterns