public class CircusPerformer
{
public List<string> PlayedItem { get; private set; }
public CircusPerformer()
{
PlayedItem=new List<string>();
}
public CircusPerformer StartShow()
{
//make a speech and start to show
return this;
}
public CircusPerformer MonkeysPlay()
{
//monkeys do some show
PlayedItem.Add("MonkeyPlay");
return this;
}
public CircusPerformer ElephantsPlay()
{
//elephants do some show
PlayedItem.Add("ElephantPlay");
return this;
}
public CircusPerformer TogetherPlay()
{
//all of the animals do some show
PlayedItem.Add("TogetherPlay");
return this;
}
public void EndShow()
{
//finish the show
}
[Test]
public void All_shows_can_be_invoked_by_fluent_way()
{
//Arrange
var circusPerformer = new CircusPerformer();
//Act
circusPerformer
.MonkeysPlay()
.ElephantsPlay()
.StartShow()
.TogetherPlay()
.EndShow();
//Assert
circusPerformer.PlayedItem.Count.Should().Be(3);
circusPerformer.PlayedItem.Contains("MonkeysPlay");
circusPerformer.PlayedItem.Contains("ElephantsPlay");
circusPerformer.PlayedItem.Contains("TogetherPlay");
}
public abstract class Performer
{
public abstract ICircusPlayer CircusPlayer { get; }
public abstract ICircusPlayer StartShow();
public abstract void EndShow();
}
public interface ICircusPlayer
{
IList PlayedItem { get; }
ICircusPlayer MonkeysPlay();
ICircusPlayer ElephantsPlay();
Performer TogetherPlay();
}
public class CircusPerformer:Performer
{
private ICircusPlayer _circusPlayer;
override public ICircusPlayer CircusPlayer { get { return _circusPlayer; } }
public override ICircusPlayer StartShow()
{
//make a speech and start to show
_circusPlayer=new CircusPlayer(this);
return _circusPlayer;
}
public override void EndShow()
{
//finish the show
}
}
public class CircusPlayer:ICircusPlayer
{
private readonly Performer _performer;
public IList PlayedItem { get; private set; }
public CircusPlayer(Performer performer)
{
_performer = performer;
PlayedItem=new List();
}
public ICircusPlayer MonkeysPlay()
{
PlayedItem.Add("MonkeyPlay");
//monkeys do some show
return this;
}
public ICircusPlayer ElephantsPlay()
{
PlayedItem.Add("ElephantPlay");
//elephants do some show
return this;
}
public Performer TogetherPlay()
{
PlayedItem.Add("TogetherPlay");
//all of the animals do some show
return _performer;
}
}
这样的API可以满足我们的要求,在马戏团circusPerformer实例上只能调用StartShow()和EndShow()
[img]http://files.jb51.net/file_images/article/201503/201533190701228.png?20152319714[/img]
调用完StartShow()后方可调用各种表演方法。
[img]http://files.jb51.net/file_images/article/201503/201533190728046.png?20152319736[/img]
当然由于我们的API很简单,所以这个设计还算说得过去,如果业务很复杂,需要考虑众多的情形或者顺序我们可以进一步完善,实现的基本思想是利用装饰者模式和扩展方法,由于园子里的dax.net在很早前就发表了相关博客[url=http://www.1sucai.cn/article/63137.htm]在C#中使用装饰器模式和扩展方法实现Fluent Interface[/url],所以大家可以去看这篇文章的实现方案,该设计应该可以说是终极模式,实现过程也较为复杂。
[b]三、泛型类的Fluent设计[/b]
泛型类中有个不算问题的问题,那就是泛型参数是无法省略的,当你在使用var list=new List<string>()这样的类型时,必须指定准确的类型string。相比而言泛型方法中的类型时可以省略的,编译器可以根据参数推断出参数类型,例如
var circusPerfomer = new CircusPerfomerWithGenericMethod();
circusPerfomer.Show<Dog>(new Dog());
circusPerfomer.Show(new Dog());
public class Drawing<TShape> where TShape :IShape
{
public TShape Shape { get; private set; }
public TShape Draw(TShape shape)
{
//drawing this shape
Shape = shape;
return shape;
}
}
public void DrawPig(Circle head, Rectangle mouth)
{
_history.Clear();
//use generic class, complier can not infer the correct type according to parameters
Register(
new Drawing<Circle>().Draw(head),
new Drawing<Rectangle>().Draw(mouth)
);
}
public static class Drawer
{
public static Drawing<TShape> For<TShape>(TShape shape) where TShape:IShape
{
return new Drawing<TShape>();
}
}
public void DrawDog(Circle head, Rectangle mouth)
{
_history.Clear();
//fluent implements
Register(
Drawer.For(head).Draw(head),
Drawer.For(mouth).Draw(mouth)
);
}
xx.MapPath(
Path.For(_student).Property(x => x.Name),
Path.For(_student).Property(x => x.Email),
Path.For(_customer).Property(x => x.Name),
Path.For(_customer).Property(x => x.Email),
Path.For(_manager).Property(x => x.Name),
Path.For(_manager).Property(x => x.Email)
)
public class Path<TModel>
{
private TModel _model;
public Path(TModel model)
{
_model = model;
}
public PropertyItem<TValue> Property<TValue>(Expression<Func<TModel, TValue>> propertyExpression)
{
var item = new PropertyItem<TValue>(propertyExpression.PropertyName(), propertyExpression.PropertyValue(_model),_model);
return item;
}
}
public static class Path
{
public static Path<TModel> For<TModel>(TModel model)
{
var path = new Path<TModel>(model);
return path;
}
}
public Validator<TValue> MapPath(params PropertyItem<TValue>[] properties)
{
foreach (var propertyItem in properties)
{
_items.Add(propertyItem);
}
return this;
}
[Test]
public void Should_validate_model_values()
{
//Arrange
var validator = new Validator<string>();
validator.MapPath(
Path.For(_student).Property(x => x.Name),
Path.For(_student).Property(x => x.Email),
Path.For(_customer).Property(x => x.Name),
Path.For(_customer).Property(x => x.Email),
Path.For(_manager).Property(x => x.Name),
Path.For(_manager).Property(x => x.Email)
)
.OnCondition((model)=>!string.IsNullOrEmpty(model.ToString()));
//Act
validator.Validate();
//Assert
var result = validator.Result();
result.Count.Should().Be(3);
result.Any(x => x.ModelType == typeof(Student) && x.Name == "Email").Should().Be(true);
result.Any(x => x.ModelType == typeof(Customer) && x.Name == "Name").Should().Be(true);
result.Any(x => x.ModelType == typeof(Manager) && x.Name == "Email").Should().Be(true);
}
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有