《模式——工程化实现及扩展》(设计模式C# 版)《原型模式 Prototype》——“自我检验" 参考答案
参考答案
1、修改Enterprise类,提供符合申报条件的有选择的序列化
[Serializable]
class Enterprise : ISerializable
{
const string NameItem = "NAME";
const string ProjectsItem = "PROJECTS";
const string StaffItem = "STAFF";
const string ProjectManagerItem = "PM";
private readonly Certification ProfessionalPm =
new Certification()
{
Name = ProjectManagerItem,
Qualification = QualificationOptions.Professional
};
public string Name { get; set; }
public Project[] Projects { get; set; }
public Employee[] Staff { get; set; }
/// <summary>
/// 构造函数
/// </summary>
public Enterprise()
{
}
/// <summary>
/// 构造函数
/// 还原过程
/// </summary>
/// <param name="info"></param>
/// <param name="context"></param>
protected Enterprise(SerializationInfo info, StreamingContext context)
{
Name = info.GetString(NameItem);
Projects = (Project[])info.GetValue(ProjectsItem, typeof(Project[]));
Staff = (Employee[])info.GetValue(StaffItem, typeof(Employee[]));
}
/// <summary>
/// 原型方法
/// </summary>
/// <returns></returns>
/// <remarks>作为示例,没有抽象独立的原型类型接口IPrototype</remarks>
public Enterprise Clone()
{
var graph = SerializationHelper.SerializeObjectToString(this);
return SerializationHelper.DeserializeStringToObject<Enterprise>(graph);
}
/// <summary>
/// 自定义序列化过程
/// </summary>
/// <param name="info"></param>
/// <param name="context"></param>
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue(NameItem, Name);if ((Projects != null) && (Projects.Count() > 0))
{
var items = Projects.Where
(
x =>
(DateTime.Now.Year - x.EndYear <= 2)
&& x.Scale > 3000
);
if (items != null)
info.AddValue(ProjectsItem, items.ToArray());
}
if (Staff != null)
{
var items =
from employee in Staff
where
(employee.Certificates != null)
&& (employee.Certificates.Count() > 0)
&& (employee.Certificates.Where(x =>
string.Equals(x.Name, ProjectManagerItem) &&
x.CompareTo(ProfessionalPm) >= 0).Count() > 0)
select new Employee()
{
Name = employee.Name,
Certificates = employee.Certificates.Where(x => x.CompareTo(ProfessionalPm) > 0).ToArray()
};
if ((items != null) && (items.Count() > 0))
info.AddValue(StaffItem, items.ToArray());
}
}
class Enterprise : ISerializable
{
const string NameItem = "NAME";
const string ProjectsItem = "PROJECTS";
const string StaffItem = "STAFF";
const string ProjectManagerItem = "PM";
private readonly Certification ProfessionalPm =
new Certification()
{
Name = ProjectManagerItem,
Qualification = QualificationOptions.Professional
};
public string Name { get; set; }
public Project[] Projects { get; set; }
public Employee[] Staff { get; set; }
/// <summary>
/// 构造函数
/// </summary>
public Enterprise()
{
}
/// <summary>
/// 构造函数
/// 还原过程
/// </summary>
/// <param name="info"></param>
/// <param name="context"></param>
protected Enterprise(SerializationInfo info, StreamingContext context)
{
Name = info.GetString(NameItem);
Projects = (Project[])info.GetValue(ProjectsItem, typeof(Project[]));
Staff = (Employee[])info.GetValue(StaffItem, typeof(Employee[]));
}
/// <summary>
/// 原型方法
/// </summary>
/// <returns></returns>
/// <remarks>作为示例,没有抽象独立的原型类型接口IPrototype</remarks>
public Enterprise Clone()
{
var graph = SerializationHelper.SerializeObjectToString(this);
return SerializationHelper.DeserializeStringToObject<Enterprise>(graph);
}
/// <summary>
/// 自定义序列化过程
/// </summary>
/// <param name="info"></param>
/// <param name="context"></param>
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue(NameItem, Name);if ((Projects != null) && (Projects.Count() > 0))
{
var items = Projects.Where
(
x =>
(DateTime.Now.Year - x.EndYear <= 2)
&& x.Scale > 3000
);
if (items != null)
info.AddValue(ProjectsItem, items.ToArray());
}
if (Staff != null)
{
var items =
from employee in Staff
where
(employee.Certificates != null)
&& (employee.Certificates.Count() > 0)
&& (employee.Certificates.Where(x =>
string.Equals(x.Name, ProjectManagerItem) &&
x.CompareTo(ProfessionalPm) >= 0).Count() > 0)
select new Employee()
{
Name = employee.Name,
Certificates = employee.Certificates.Where(x => x.CompareTo(ProfessionalPm) > 0).ToArray()
};
if ((items != null) && (items.Count() > 0))
info.AddValue(StaffItem, items.ToArray());
}
}
2、准备测试数据
Enterprise enterprise;
[TestInitialize]
public void Initialize()
{
var thisYear = DateTime.Now.Year;
enterprise = new Enterprise()
{
Name = "A",
Projects = new Project[]
{
// 金额不符合
new Project() {EndYear = thisYear, Scale = 1500},
// 符合
new Project() {EndYear = thisYear - 1, Scale = 3500},
// 时间不符合
new Project() {EndYear = thisYear - 3, Scale = 5000},
// 符合
new Project() {EndYear = thisYear - 1, Scale = 7500}
},
Staff = new Employee[]
{
// PM级别不符合
new Employee(){
Name = "E1",
Certificates = new Certification[]
{
new Certification()
{
Name="PM",
Qualification = QualificationOptions.Assisstant
},
new Certification()
{
Name="ARCH",
Qualification = QualificationOptions.Professional
}
}
},
// 符合
new Employee(){
Name = "E2",
Certificates = new Certification[]
{
new Certification()
{
Name="PM",
Qualification = QualificationOptions.Assisstant
},
new Certification()
{
Name="PM",
Qualification = QualificationOptions.Senior
}
}
},
// 证书类别不符合
new Employee(){
Name = "E3",
Certificates = new Certification[]
{
new Certification()
{
Name="ARCH",
Qualification = QualificationOptions.Assisstant
},
new Certification()
{
Name="ARCH",
Qualification = QualificationOptions.Senior
}
}
},
// 符合
new Employee(){
Name = "E4",
Certificates = new Certification[]
{
new Certification()
{
Name="PM",
Qualification = QualificationOptions.Assisstant
},
new Certification()
{
Name="PM",
Qualification = QualificationOptions.Professional
},
new Certification()
{
Name="PM",
Qualification = QualificationOptions.Assisstant
},
new Certification()
{
Name="PM",
Qualification = QualificationOptions.Principal
}
}
},
}
};
}
[TestInitialize]
public void Initialize()
{
var thisYear = DateTime.Now.Year;
enterprise = new Enterprise()
{
Name = "A",
Projects = new Project[]
{
// 金额不符合
new Project() {EndYear = thisYear, Scale = 1500},
// 符合
new Project() {EndYear = thisYear - 1, Scale = 3500},
// 时间不符合
new Project() {EndYear = thisYear - 3, Scale = 5000},
// 符合
new Project() {EndYear = thisYear - 1, Scale = 7500}
},
Staff = new Employee[]
{
// PM级别不符合
new Employee(){
Name = "E1",
Certificates = new Certification[]
{
new Certification()
{
Name="PM",
Qualification = QualificationOptions.Assisstant
},
new Certification()
{
Name="ARCH",
Qualification = QualificationOptions.Professional
}
}
},
// 符合
new Employee(){
Name = "E2",
Certificates = new Certification[]
{
new Certification()
{
Name="PM",
Qualification = QualificationOptions.Assisstant
},
new Certification()
{
Name="PM",
Qualification = QualificationOptions.Senior
}
}
},
// 证书类别不符合
new Employee(){
Name = "E3",
Certificates = new Certification[]
{
new Certification()
{
Name="ARCH",
Qualification = QualificationOptions.Assisstant
},
new Certification()
{
Name="ARCH",
Qualification = QualificationOptions.Senior
}
}
},
// 符合
new Employee(){
Name = "E4",
Certificates = new Certification[]
{
new Certification()
{
Name="PM",
Qualification = QualificationOptions.Assisstant
},
new Certification()
{
Name="PM",
Qualification = QualificationOptions.Professional
},
new Certification()
{
Name="PM",
Qualification = QualificationOptions.Assisstant
},
new Certification()
{
Name="PM",
Qualification = QualificationOptions.Principal
}
}
},
}
};
}
3、执行单元测试
[TestMethod]
public void Test()
{
Initialize();
var clone = enterprise.Clone();
Assert.AreEqual<string>(enterprise.Name, clone.Name);
// 企业结项项目信息
Assert.AreEqual<int>(2, clone.Projects.Count());
// 企业人员信息
Assert.AreEqual<int>(2, clone.Staff.Count());
}
public void Test()
{
Initialize();
var clone = enterprise.Clone();
Assert.AreEqual<string>(enterprise.Name, clone.Name);
// 企业结项项目信息
Assert.AreEqual<int>(2, clone.Projects.Count());
// 企业人员信息
Assert.AreEqual<int>(2, clone.Staff.Count());
}
Output窗口测试结果
------ Test started: Assembly: Prototype.Tests.dll ------
1 passed, 0 failed, 0 skipped, took 0.32 seconds (Ad hoc).
1 passed, 0 failed, 0 skipped, took 0.32 seconds (Ad hoc).
贸易电子化,技术全球化
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?