码迷,mamicode.com
首页 > 其他好文 > 详细

表单兼容类型设计

时间:2014-10-12 02:12:07      阅读:223      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   io   使用   ar   for   strong   

以前的我认为,相同的表单,若有后台代码,那么它对应的应该是一套业务,只能为这个功能服务。但是后来的需求打翻了我的认识。

以前我做的一条线是实现如下功能

bubuko.com,布布扣

这个是一条线的功能,结合工作流,4个活动点对应四个表单。

后来在做第四个功能线的时候发现一部分与功能一相同。但是其中用到的类与对象却不相同。但是页面是稍微变化。还是可以复用页面的。

 bubuko.com,布布扣

需求功能大题是一样的。类的设计是不同的子类设计。那么就需要修改原来的代码实现了。

看设计图

bubuko.com,布布扣

先前所有后台的泛型为第一个,后续的复用页面需要用第二个泛型类,但是他们都共同继承同一个基类。如何根据不同的功能保存不同的泛型类。使一个表单兼容两个不同的类型,这是设计时需要考虑的。

我们的解决方式是在基类中添加了一个selfType的属性,标记了一个使用者的类型。这样在准备数据的时候传递的是基类,但是自身却携带了是某一个类型。

而到了具体的表单页面时,根据自身的selfType判断类型,继而转换不同的子类,保存数据。

我们来看看一个实例吧

设计的思路:

  •  首先加载基类,而后判断是否为空,若为空创建第子类的类型
  • 若不为空,根据父类携带类型,判断是子类的哪个类型,根据Id,加载子类,将父类指向子类
  • 表单根据父类携带的类型,保存时进行数据类型强转

Control准备数据

//以下为MVC中control中数据准备
	                   String resourceID = process.ResourceID;//父类加载数据,后续判断是否为空,指向不同自来
			EnsureKeyedCapabilityIndicatorFormBase data = EnsureKeyedCapabilityIndicatorFormBaseAdapter.Instance.Load(resourceID);
			int operateYear = WebUtility.GetRequestQueryValue("operateYear", DateTime.Now.SimulateTime().Year);

			if (data == null)
			{
				//父类为空,应用指向子类,创建子类对象,//方便后续转换类型
				data = new EnsureGroupKeyedCapabilityIndicatorForm()
				{
					SelfTypeName = typeof(EnsureGroupKeyedCapabilityIndicatorForm).Name,

					ID = resourceID,
					CreatorID = user.ID,
					CreatorName = user.DisplayName,
					CreateTime = DateTime.Now.SimulateTime(),
					OperateYear = operateYear,
					PlanStartYear = operateYear + 1,
					Subject = operateYear + "确认历史能力",
					ProcState = WfProcessStatus.NotRunning
				};
				var companyCapabilitySummary = data.InitDefaultCompanyCapability();
				CompanyCapabilitySummaryTransAdapter.Instance.Update(companyCapabilitySummary);
				EnsureGroupKeyedCapabilityIndicatorFormAdapter.Instance.Update((EnsureGroupKeyedCapabilityIndicatorForm)data);

			}
			else
			{
				//已经是有数据了,根据父类携带类型,判断是子类的哪个类型,进行类型加载
				if (data.SelfTypeName == typeof(EnsureGroupKeyedCapabilityIndicatorForm).Name)
				{
					data = EnsureGroupKeyedCapabilityIndicatorFormAdapter.Instance.Load(resourceID);
				}
				else
				{
					data = EnsureBusinessModelKeyedCapabilityIndicatorFormAdapter.Instance.Load(resourceID);
					var comanys = CompanyCapabilitySummaryTransAdapter.Instance.LoadByFormCode(resourceID);
					var enBusines = (EnsureBusinessModelKeyedCapabilityIndicatorForm)data;
					//子类还需要进行辨别是新增还是已经存在的商业模式,
					if (enBusines.BusinessModelExsitsType == BusinessModelExsitsTypeEnum.Exsits)
					{
						//已经在初始化自身
						if (comanys.Count == 0)
						{
							var companyCapabilitySummary = data.InitDefaultCompanyCapability();
							CompanyCapabilitySummaryTransAdapter.Instance.Update(companyCapabilitySummary);
						}

					}
					else
					{
						//新增,使用公共代替自身
						if (comanys.Count == 0)
						{
							var companyCapabilitySummary = data.InitDefaultCompanyCapability(CompanyCapabilitySummaryTrans.IndustryAvgCodeConst);
							CompanyCapabilitySummaryTransAdapter.Instance.Update(companyCapabilitySummary);
						}
					}
					
				}

			}
			//返回基类数据,但是指向的却是之类。
			return new FormCommandStateGenericBase<EnsureKeyedCapabilityIndicatorFormBase>()
			{
				Data = data
			};

表单后台保存

表单的继承类型为基类

 public partial class EnsureCapabilityIndicatorHistoryView : ExtendViewBase<FormCommandStateGenericBase<EnsureKeyedCapabilityIndicatorFormBase>, EnsureKeyedCapabilityIndicatorFormBase>
{
	//ViewData中DatA 为control中传递过来的数据(data)
	protected override void SaveApplicationData(WfExecutorDataContext datacontext)
			{
				//还是根据携带类型辨别是哪个继承类,
				if (this.ViewData.Data.SelfTypeName == typeof(EnsureGroupKeyedCapabilityIndicatorForm).Name)
				{
					//保存时进行数据类型强转(若没有control中的父类指向子类引用,这里的转换是报错的)
					EnsureGroupKeyedCapabilityIndicatorFormAdapter.Instance.Update((EnsureGroupKeyedCapabilityIndicatorForm)this.ViewData.Data);
				}
				else
				{
					EnsureBusinessModelKeyedCapabilityIndicatorFormAdapter.Instance.Update((EnsureBusinessModelKeyedCapabilityIndicatorForm)this.ViewData.Data);
				}
			}
}

小结:

这里用到的实质为面向对象中的继承特性,父类引用指向子类,这个相信大家很熟悉的,Ilist<string> names= new List<string>()实例化的是一个IList的父类,只能使用父类的属性,若想使用List的属性,如ListforEach属性,这样的实例化是不可以使用的,必须将names强转为List。就是一个很好的例子,但是若能透彻的明白,并在设计中熟练使用,还真的是需要透彻的了解,多多思考。

 

表单兼容类型设计

标签:style   blog   http   color   io   使用   ar   for   strong   

原文地址:http://blog.csdn.net/han_yankun2009/article/details/40008287

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!