在下面的代码中,首先是if
语句块(不仅仅是“worker”条件,加上else if
)我选择了正确的filter_object
。在此相同的条件块之后,我选择过滤器对象应该应用什么过滤器。这段代码很傻。
public class Filter
{
public static List<data.Issue> fetch(string type, string filter)
{
Filter_Base filter_object = new Filter_Base(filter);
if (type == "worker")
{
filter_object = new Filter_Worker(filter);
}
else if (type == "dispatcher")
{
filter_object = new Filter_Dispatcher(filter);
}
List<data.Issue> result = new List<data.Issue>();
if (filter == "new")
{
result = filter_object.new_issues();
}
else if (filter == "ended")
{
result = filter_object.ended_issues();
}
return result;
}
}
public class Filter_Base
{
protected string _filter;
public Filter_Base(string filter)
{
_filter = filter;
}
public virtual List<data.Issue> new_issues()
{
return new List<data.Issue>();
}
public virtual List<data.Issue> ended_issues()
{
return new List<data.Issue>();
}
}
public class Filter_Worker : Filter_Base
{
public Filter_Worker(string filter) :
base(filter)
{ }
public override List<data.Issue> new_issues()
{
return (from i in data.db.GetInstance().Issues
where (new int[] { 4, 5 }).Contains(i.RequestStatusId)
select i).Take(10).ToList();
}
}
public class Filter_Dispatcher : Filter_Base
{
public Filter_Dispatcher(string filter) :
base(filter)
{ }
}
它将用于某种形式:
Filter.fetch("worker", "new");
这段代码意味着,对于属于角色“工作者”的用户,只会获取“新”问题(这是某种小而简单的CRM)。或者另一个:
Filter.fetch("dispatcher", "ended"); // here we get finished issues for dispatcher role
有关如何改进它的任何建议吗?
答案 0 :(得分:2)
我假设你问你如何修剪Fetch方法。我会使用泛型
public static List<data.Issue> Fetch<T>( string filter ) where T : FilterBase, new()
{
var filterBase = new T();
filterBase.Initialize( filter );
List<data.Issue> result;
if ( IsNew( filter ) )
result = filterBase.NewIssues();
else if ( IsEnded( filter ) )
result = filterBase.EndedIssues();
else
result = new List<data.Issue>();
return result;
}
这需要:
Initialize
的虚方法,它在FilterBase上接受一个字符串。Filter
类上的IsNew和IsEnded静态函数,以便Fetch
方法可以确定您可以使用哪个函数。另一个解决方案是Fetch
的附加委托参数,以确定应该调用哪个方法。如何改进代码的其余部分?
答案 1 :(得分:1)
这可能看起来很长,但我会利用属性和反射来尝试实现这一目标。
像
这样的东西属性:
class FilterType : Attribute
{
public string Filter;
public FilterType(string filter)
{
Filter = filter;
}
}
class FilterMethod : Attribute
{
public string Filter;
public FilterMethod(string filter)
{
Filter = filter;
}
}
具有属性标记的类
public class Filter_Base
{
protected string _filter;
public Filter_Base(string filter)
{
_filter = filter;
}
[FilterMethod("new")]
public virtual List<string> new_issues()
{
return new List<string>();
}
}
[FilterType("Worker")]
public class Filter_Worker : Filter_Base
{
public Filter_Worker(string filter) :
base(filter)
{ }
public override List<string> new_issues()
{
return new List<string>();
}
}
过滤方法
private static List<string> GetInstanceList(string type, string filter)
{
//get all classes implementing FilterType Attribute
var dict = AppDomain.CurrentDomain.GetAssemblies().
SelectMany(x => x.GetTypes()).
Where(x => x.GetCustomAttributes(typeof(FilterType), false).Length > 0).
Select(x => new { ((FilterType)x.GetCustomAttributes(typeof(FilterType), false)[0]).Filter, x }).
ToDictionary(x => x.Filter);
Filter_Base instance = (Filter_Base)Activator.CreateInstance(dict[type].x, filter);
var methods = instance.GetType().GetMembers().
Where(x => x.GetCustomAttributes(typeof(FilterMethod), true).Length > 0).
Select(x => new { ((FilterMethod)x.GetCustomAttributes(typeof(FilterMethod), true)[0]).Filter, x }).
ToDictionary(x => x.Filter);
return (List<string>)instance.GetType().GetMethod(methods[filter].x.Name).Invoke(instance, null);
}
最后致电
List<string> instance = GetInstanceList("Worker", "new");
答案 2 :(得分:1)
ioc
.RegisterType<IDataStrategy, FilterWorker>("worker")
/// more filters
.RegisterType<IDataStrategy, FilterDispatcher>("dispatcher");
或者工厂对象至少可以重构你的代码,但我离题了......
当你在它时,丢失基类并实现一个接口:
public interface IDataStrategy
{
IEnumerable<Data.Issue> FetchNew();
IEnumerable<Data.Issue> FetchEnded();
}
按建议使用枚举:
public enum FilterType
{
New,
Ended
}
现在在你的获取功能
public IEnumerable<Data.Issue> Fetch(string dataType, FilterType filterType)
{
var strategy = ioc.Resolve<IDataStrategy>(dataType);
IEnumerable<Data.Issue> results = null;
switch(filterType)
{
case FilterType.New:
results = strategy.FetchNew();
default:
results = strategy.Ended();
}
return results;
}