我们需要实现一个功能来生成巨大的 xml 文档来导出记录。
我们的情况如下:
所以,我做了接口生成Xml
public interface IGenerateXml
{
ResourceIntensiveObject1 Student { get; set; }
ResourceIntensiveObject2 Course { get; set; }
ResourceIntensiveObject3 User { get; set; }
XmlElement Generate();
}
我不想在每个类中声明公共对象。因此,我创建了可用于传递这些对象的基类。并非所有部分都需要访问这些对象,但大多数部分都需要它们。
public class GenerateXmlBase
{
public ResourceIntensiveObject1 Student { get; set; }
public ResourceIntensiveObject2 Course { get; set; }
public ResourceIntensiveObject3 User { get; set; }
}
然后创建类,实现接口,继承基类
public class GenerateSection1 : GenerateXmlBase, IGenerateXml
{
public XmlElement Generate()
{
// some codes to return Xml
return null;
}
}
public class GenerateSection2 : GenerateXmlBase, IGenerateXml
{
public XmlElement Generate()
{
// some codes to return Xml
return null;
}
}
public class GenerateSection3 : GenerateXmlBase, IGenerateXml
{
public XmlElement Generate()
{
// some codes to return Xml
return null;
}
}
通过这种方式,我为每个部分获得了可测试、易于模拟的类。然而,当我尝试将所有这些代码组合在一起时,我得到了一些重复的代码,它们一次又一次地做同样的事情(将创建的对象分配给类)。请看以下代码:
void GenerateAndSaveXmlDocument()
{
// loading these classes are resource intensive and takes time
// so load only once and pass down to the sub classes
var _student = new ResourceIntensiveObject1();
var _course = new ResourceIntensiveObject2();
var _user = new ResourceIntensiveObject3();
IGenerateXml clsGenerateSection1 = new GenerateSection1();
IGenerateXml clsGenerateSection2 = new GenerateSection2();
IGenerateXml clsGenerateSection3 = new GenerateSection3();
// code goes on for other 9 classes
// <--------- this is where repetitive codes start
clsGenerateSection1.Student = _student;
clsGenerateSection1.Course = _course;
clsGenerateSection1.User = _user;
clsGenerateSection2.Student = _student;
clsGenerateSection2.Course = _course;
clsGenerateSection2.User = _user;
// this one needs only 2 classes
clsGenerateSection3.Student = _student;
clsGenerateSection3.Course = _course;
// and other 9 classes codes which use 2/3 objects
// ........
// generate, combine and save final xml
}
我想知道如何有效地编码以删除那些重复的代码?
PS:我不想在Generate()
方法中传递这些对象,因为我们不确定生成 XML 需要多少资源密集型对象。目前,我们只查看了 2 个部分,未来可能会增加。
大量重复代码来自属性赋值语句。考虑一个抽象基类GenerateXmlAbstract
,其是组合GenerateXmlBase
和IGenerateXml
:
public abstract class GenerateXmlAbstract {
public ResourceIntensiveObject1 Student { get; private set; }
public ResourceIntensiveObject2 Course { get; private set; }
public ResourceIntensiveObject3 User { get; private set; }
public GenerateXmlAbstract(
ResourceIntensiveObject1 student,
ResourceIntensiveObject2 course,
ResourceIntensiveObject3 user
) {
Student = student;
Course = course;
User = user;
}
public abstract XmlElement Generate();
}
需要注意的关键是属性赋值语句位于抽象基类构造函数中。这样,可以在继承类中调用构造函数:
public class GenerateSection1 : GenerateXmlAbstract {
public GenerateSection1(
ResourceIntensiveObject1 student,
ResourceIntensiveObject2 course,
ResourceIntensiveObject3 user
) : base(student, course, user) { }
public XmlElement Generate() {
// some codes to return Xml
return null;
}
}
然后可以通过将必要的依赖项传递给构造函数来实例化继承的具体类,这也避免了在Generate
方法中传递它们:
void GenerateAndSaveXmlDocument() {
// loading these classes are resource intensive and takes time
// so load only once and pass down to the sub classes
var _student = new ResourceIntensiveObject1();
var _course = new ResourceIntensiveObject2();
var _user = new ResourceIntensiveObject3();
IGenerateXml clsGenerateSection1 = new GenerateSection1(_student, _course, _user);
IGenerateXml clsGenerateSection2 = new GenerateSection2(_student, _course, _user);
IGenerateXml clsGenerateSection3 = new GenerateSection3(_student, _course, _user);
// code goes on for other 9 classes
// generate, combine and save final xml
}
对于不使用所有三个依赖项的类,您可能会考虑传递 null,在GenerateXmlAbstract
类中定义另一个带有一两个参数的构造函数,或者构建一个更细粒度的继承树,其中并非所有类都包含所有依赖项。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句