先写个草稿
示例等后面再加上去 先把灵感记下来
代码下载地址:https://download.csdn.net/download/sinat_30224769/10632514
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
[System.Runtime.InteropServices.ComVisible(true)]
public class CaseRange : Attribute
{
public Func<bool> Case { get; set; }
public CaseRange()
{
throw new Exception("必须添加函数执行的条件或范围");
}
/// <summary>
/// 给方法添加执行条件
/// </summary>
/// <param name="Case"></param>
public CaseRange(Func<bool> Case)
{
this.Case = Case;
}
}
引用:策略模式: https://blog.csdn.net/u012124438/article/details/70039943/
----------------------------------------------------------------分割线--------------------------------------------------------
时间是检验真理的唯一标准
现在以支付为例
支付类中有 支付宝、微信
各有方法 主扫、被扫、获取自己的名称(测试打印当前类信息)
第一需要Attribute类
目前先做类标记 解决 工厂模式 if else
起个名字就叫做(类枚举特性标记)
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
[System.Runtime.InteropServices.ComVisible(true)]
public class ClassEnumConditionAttribute : Attribute
{
public PayTypeEnum EnumCondition { get; set; }
/// <summary>
/// 给方法添加执行条件
/// </summary>
/// <param name="Case"></param>
public ClassEnumConditionAttribute(PayTypeEnum EnumCondition)
{
this.EnumCondition = EnumCondition;
}
}
第二开始构造个接口
和实现具体的类
构造接口
public interface IPayMentBase
{
string WhoAmI();
bool MainPay();
bool ScanPay(string QRCode);
}
实现类 这里要记住命名空间尽量使用同一个 可以提高效率
namespace StrategicFactory.Model.PayMent
{
[ClassEnumCondition(PayTypeEnum.AliPay)]
public class AliPay : IPayMentBase
{
public bool MainPay()
{
return true;
}
public bool ScanPay(string QRCode)
{
return true;
}
public string WhoAmI()
{
return "AliPay";
}
}
}
namespace StrategicFactory.Model.PayMent
{
[ClassEnumCondition(PayTypeEnum.WeiXinPay)]
public class WeixinPay : IPayMentBase
{
public bool MainPay()
{
return true;
}
public bool ScanPay(string QRCode)
{
return true;
}
public string WhoAmI()
{
return "WeixinPay";
}
}
}
为了调用方便 起一个 枚举类作为 选择的条件 这里就相当于原来的 ifelse 需要判断的地方
public enum PayTypeEnum
{
AliPay,
WeiXinPay
}
最关键的就是 筛选了
第一个方法是用来测试的方法
第二个 因为要睡觉了 所以有空在写(应该还可以继续简化,减少内部干扰减少依赖)
public class PayMentFactory<T> where T : Attribute
{
/// <summary>
/// 获取实例 定义式(返回具体对象)
/// </summary>
/// <param name="Case"></param>
/// <returns></returns>
public IPayMentBase GetPayMent(Func<T, bool> Case)
{
var Namespace = "StrategicFactory.Model.PayMent";//减少搜索的数据量定位类更快(可外部传入)
//var xx = Assembly.GetExecutingAssembly().GetTypes().Where(x => x.Namespace == Namespace).ToArray();
//搜索命名空间中的类
//如果是外部DLL Assembly.Load("namespace").GetTypes();
var patment = Assembly.GetExecutingAssembly().GetTypes().Where(x => x.Namespace == Namespace).FirstOrDefault(
x =>
{
var tempAttrr = Attribute.GetCustomAttribute(x, typeof(T));
if (tempAttrr == null) return false;
if (!(tempAttrr is T)) return false;
return Case(tempAttrr as T);
}
);
if (patment == null)
{
throw new Exception("错误");
}
dynamic obj = patment.Assembly.CreateInstance(patment.FullName);
return (IPayMentBase)obj;
}
/// <summary>
/// 获取实例 解耦式 返回object对象 在外部转化
/// </summary>
/// <param name="Case"></param>
/// <param name="Namespace">减少搜索的数据量定位类更快(可外部传入)</param>
/// <returns></returns>
public object GetPayMent2(Func<T, bool> Case, string Namespace = "")
{
//搜索命名空间中的类
//如果是外部DLL Assembly.Load("namespace").GetTypes();
var patment = Assembly.GetExecutingAssembly().GetTypes().Where(x => x.Namespace == Namespace).FirstOrDefault(
x =>
{
var tempAttrr = Attribute.GetCustomAttribute(x, typeof(T));
if (tempAttrr == null) return false;
if (!(tempAttrr is T)) return false;
return Case(tempAttrr as T);
}
);
if (patment == null)
{
throw new Exception("错误");
}
dynamic obj = patment.Assembly.CreateInstance(patment.FullName);
return obj;
}
}
都准备好了 那就尝试着调用一下
namespace StrategicFactory
{
class Program
{
static void Main(string[] args)
{
PayMentFactory<ClassEnumConditionAttribute> tempFactory = new PayMentFactory<ClassEnumConditionAttribute>();
var Pay = tempFactory.GetPayMent(x => x.EnumCondition == PayTypeEnum.AliPay);
Console.WriteLine(Pay.WhoAmI());
Pay = tempFactory.GetPayMent(x => x.EnumCondition == PayTypeEnum.WeiXinPay);
Console.WriteLine(Pay.WhoAmI());
Console.ReadLine();
}
}
}
调用成功===
这里提一下,调用工厂方法的地方是不知道具体传入的是什么类型的
而是进入以后通过 条件判断选择 return new AliPay() 还是 return new WeixinPay();
具体来说因该是 Reflection配合 Attribute 解决的 ,不过感觉反射还是有一定风险的,在处理结果的时候判断要全面
---
接下来将尝试 方法的 Attribute消除 ifelse
--
那么今天就先休息了~