zoukankan      html  css  js  c++  java
  • 表单兼容类型设计

    曾经的我觉得,同样的表单,若有后台代码,那么它相应的应该是一套业务,仅仅能为这个功能服务。可是后来的需求打翻了我的认识。

    曾经我做的一条线是实现例如以下功能


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

    后来在做第四个功能线的时候发现一部分与功能一同样。

    可是当中用到的类与对象却不同样。

    可是页面是略微变化。

    还是能够复用页面的。

     

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

    看设计图


    先前全部后台的泛型为第一个,兴许的复用页面须要用第二个泛型类,可是他们都共同继承同一个基类。怎样依据不同的功能保存不同的泛型类。

    使一个表单兼容两个不同的类型,这是设计时须要考虑的。

    我们的解决方案是在基类中加入了一个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

    就是一个非常好的样例。可是若能透彻的明确,并在设计中熟练使用。还真的是须要透彻的了解,多多思考。

     

  • 相关阅读:
    1、编写一个简单的C++程序
    96. Unique Binary Search Trees
    python 操作redis
    json.loads的一个很有意思的现象
    No changes detected
    leetcode 127 wordladder
    django uwsgi websocket踩坑
    you need to build uWSGI with SSL support to use the websocket handshake api function !!!
    pyinstaller 出现str error
    数据库的读现象
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/7040330.html
Copyright © 2011-2022 走看看