[英]what is the best way of providing instant search functionality as a user types in a textbox
[英]What is the best way to "adorn objects with functionality"?
我做了下面的例子,它使工厂能够打包具有功能的对象,但问题是功能与对象分离。
我的最终目标是附加功能,例如log 、 save和display ,这些功能对每个不同对象具有的特定属性进行操作。
我将如何保留此示例的外部装饰方面,但启用诸如“保存”将对象的数据保存到数据库或记录其活动的“日志”等功能?
using System;
using System.Collections.Generic;
namespace FuncAdorn3923
{
class Program
{
static void Main(string[] args)
{
Customer customer = new Customer();
ObjectFactory.Instance.AdornFunctionality(customer, "add");
Console.WriteLine(customer.CallAlgorithm("add", 64, 36));
Employee employee = new Employee();
ObjectFactory.Instance.AdornFunctionality(employee, "add");
ObjectFactory.Instance.AdornFunctionality(employee, "subtract");
Console.WriteLine(employee.CallAlgorithm("add", 5, 15));
Console.WriteLine(employee.CallAlgorithm("subtract", 66, 16));
Console.ReadLine();
}
}
public class ObjectFactory
{
private static ObjectFactory singleton;
public void AdornFunctionality(AdornedObject ao, string idCode)
{
Func<int, int, int> add = (i, j) => i + j;
Func<int, int, int> subtract = (i, j) => i - j;
switch (idCode)
{
case "add":
ao.LoadAlgorithm(idCode, add);
break;
case "subtract":
ao.LoadAlgorithm(idCode, subtract);
break;
}
}
public static ObjectFactory Instance
{
get
{
if (singleton == null)
singleton = new ObjectFactory();
return singleton;
}
}
}
public abstract class AdornedObject
{
private Dictionary<string, Func<int, int, int>> algorithms =
new Dictionary<string, Func<int, int, int>>();
public void LoadAlgorithm(string idCode, Func<int,int,int> func)
{
algorithms.Add(idCode, func);
}
public int CallAlgorithm(string idCode, int i1, int i2)
{
Func<int,int,int> func = algorithms[idCode];
return func.Invoke(i1, i2);
}
}
public class Customer : AdornedObject
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int NumberOfProductsBought { get; set; }
}
public class Employee : AdornedObject
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
}
我个人会推荐一种更好的设计模式,比如访问者模式,但不管怎样,你可以通过抛弃类型安全来让你的代码工作。 使用Delegate
而不是它的派生类Func
和Action
:
static void Main(string[] args)
{
Customer customer = new Customer();
ObjectFactory.Instance.AdornFunctionality(customer, "add");
Console.WriteLine(customer.CallAlgorithm("add", 64, 36));
Employee employee = new Employee();
ObjectFactory.Instance.AdornFunctionality(employee, "add");
ObjectFactory.Instance.AdornFunctionality(employee, "subtract");
ObjectFactory.Instance.AdornFunctionality(employee, "save");
Console.WriteLine(employee.CallAlgorithm("add", 5, 15));
Console.WriteLine(employee.CallAlgorithm("subtract", 66, 16));
Console.WriteLine(employee.CallAlgorithm("save"));
Console.ReadLine();
}
}
public class ObjectFactory
{
private static ObjectFactory singleton;
public void AdornFunctionality(AdornedObject ao, string idCode)
{
Func<int, int, int> add = (i, j) => i + j;
Func<int, int, int> subtract = (i, j) => i - j;
Action save = () => Console.WriteLine("{0} has been saved", ao.ToString());
switch (idCode)
{
case "add":
ao.LoadAlgorithm(idCode, add);
break;
case "subtract":
ao.LoadAlgorithm(idCode, subtract);
break;
case "save":
ao.LoadAlgorithm(idCode, save);
break;
}
}
public static ObjectFactory Instance
{
get
{
if (singleton == null)
singleton = new ObjectFactory();
return singleton;
}
}
}
public abstract class AdornedObject
{
private Dictionary<string, Delegate> algorithms = new Dictionary<string, Delegate>();
public void LoadAlgorithm(string idCode, Delegate func)
{
algorithms.Add(idCode, func);
}
public object CallAlgorithm(string idCode, params object[] args)
{
Delegate func = algorithms[idCode];
return func.DynamicInvoke(args);
}
}
这看起来像是访问者模式的经典案例。
算法(访问者)需要根据他们装饰(或访问)的对象进行定制,或者至少根据您的装饰对象实现的某些接口进行定制。
例如,您的Employee
对象可能具有如下所示的方法:
public class Employee: IEmployee {
public void Accept(IEmployeeAlgorithm algorithm) {
algorithm.Visit(this);
}
}
IEmployeeAlgorithm
对象将具有与此类似的接口(这些可以很容易地成为Action<Employee>
委托,或根据需要使用其他签名):
public interface IEmployeeAlgorithm {
void Visit(IEmployee employee);
}
最后,如果您想提供算法键并动态调用它们,您可以通过将它们存储在IDictionary<string, IEmployeeAlgorithm>
成员中,以类似于您现在所获得的方式执行此操作。
我会查看PostSharp项目。 它们允许这种关注点分离并启用一些简单的方法来实现这一点。 它们允许您在外部定义在运行时添加到类/属性的代码。 我不确定您的具体要求(或此特定示例),但您应该检查一下。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.