C#员工薪资计算程序_第1页
C#员工薪资计算程序_第2页
C#员工薪资计算程序_第3页
C#员工薪资计算程序_第4页
C#员工薪资计算程序_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、面向对象课程设计报告设计题目:员工薪资计算专业:软件工程班级:软工1201学号:3120305127姓名:陆顺天日期:2014.03.21一、设计任务与要求1. 设计任务: 假设要为某个公司编写员工工资支付程序。一般工人(Worker)按每月工作的天数计算工资;销售人员(Salesman)在基本工资基础上每月还有销售提成;经理(Manager) 每月按固定工资支付,临时工(Floater )按小时支付。经理工资计算:月工资()销售人员工资计算:基本工资+每件产品提成额*销售的产品数量一般工人工资计算:每天工资额*工作天数临时工工资计算:每小时工资额*总工作小时数文本界面为:1新增员工

2、信息2删除员工信息3员工信息搜索(按姓名)5员工信息统计(按姓名或工资或类别)6员工信息分类存储7员工信息导入8按工资排序9退出2. 课程设计的要求:要求设计抽象类(Employee)描述所有员工的共同特性(如姓名,性别,出生日期,员工类别),含有计算工资的纯虚函数computeSalay(),所有员工用该方法计薪。要求用多态实现。二、系统分析1.需求分析:实现文本界面实现xml格式的数据保存实现文本格式的数据输入输出实现控制台的操作控制实现薪资计算与薪资排序2.系统分层程序分为业务逻辑层和界面层.业务逻辑层:实现员工薪资计算逻辑界面层:实现文本界面的显示三、程序设计1. 界面设计实现文本、多

3、窗口的界面显示和操作.采用多态机制为每一个窗口建立共同的基类.2. 员工类设计(部分代码展示)/ <summary> / 所有员工类的抽象超类 / </summary> public abstract class Employee : IComparable, ITextDisplayable / <summary> / 构造员工实例 / </summary> protected Employee(string name, bool isMan) this.Name = name; this.IsMan = isMan; / <summar

4、y> / 工厂方法,创建特定类型的员工 / </summary> / <param name="name">员工的姓名</param> / <param name="birthday">员工的出生日期</param> / <param name="isMan">员工是否为男性</param> / <param name="typeCode">员工职位类型码</param> private static

5、Employee Create(string name, bool isMan, EmployeType typeCode) switch (typeCode.Code) case EmployeType.TypeCode.Worker: return new Worker(name, isMan); case EmployeType.TypeCode.Salesman: return new Salesman(name, isMan); case EmployeType.TypeCode.Manager: return new Manager(name, isMan); case Emplo

6、yeType.TypeCode.Floater: return new Floater(name, isMan); default: throw new Exception("错误的员工类型"); #region 员工属性 / <summary> / 获取或设置员工的姓名(仅支持中文名称) / </summary> / <value>员工的姓名</value> public string Name get; set; / <summary> / 获取一个布尔值,标示员工的性别,如果是男性,返回true. / <

7、;/summary> / <value>是否为男性</value> public bool IsMan get; set; / <summary> / 获取员工类型 / </summary> / <value>员工类型码</value> public abstract EmployeType EmployeType get; / <summary> / 计算员工的薪资 / </summary> / <returns>员工的薪资</returns> public abst

8、ract Salay ComputeSalay(); #endregion #region 文本格式读写对象 / <summary> / 主动从控制台接收数据获取员工对象 / </summary> public static Employee Create() Console.Write("tt姓名: "); string name = Console.ReadLine(); Console.Write("tt性别: "); bool isMen = Console.ReadLine().Equals("男")

9、 ? true : false; Console.Write("tt职位码: "); int code; try code = int.Parse(Console.ReadLine(); catch (Exception) code = 0; EmployeType type = new EmployeType(EmployeType.TypeCode)code); Employee staff = Employee.Create(name, isMen, type); staff.ReadAttribute(); return staff; / <summary&g

10、t; / 主动从控制台获取属性 / </summary> protected virtual void ReadAttribute() / <summary> / 返回员工的文字表示 / </summary> public virtual string TextInterfaces get return " 职务: " + this.EmployeType.ToString() + "t姓名: " + this.Name + "t性别: " + (this.IsMan ? "男"

11、 : "女") + "t薪资: " + this.ComputeSalay().ToString(); #endregion #region IComparable 成员 public int CompareTo(object obj) Employee target = obj as Employee; return this.ComputeSalay().Dollars.CompareTo(target.ComputeSalay().Dollars); #endregion 1. 采用Replace typecode with subclasses的

12、重构手法(参考重构 改善既有代码的设计),将标示员工职务的类型码用子类取代,建立继承体系。以多态机制取代switch的使用,使程序的复用性和可读性增强,使未来添加的新的职务类型更加容易。这里如果使用Replace typecode with State/Strategy(参考 GOF设计模式)则更好,为职务类型建立继承体系而不是从员工类中提取,考虑到现实中一个员工的职务是可变的(升职),然而类是不可改变的,所以这种方法更符合实际要求,也减轻了员工类处理薪资计算等细节的负担。2. 工厂方法的使用。也是参考Abstract Factory设计模式,将Employee类的构造函数设置为保护方法,将子

13、类的访问权限设置为私有,并为每一个子类建立一个工厂方法。这样,用户只用提供员工类型码和员工参数就可以创建特定类型的员工,也就是说,员工的继承体系被隐藏起来,对于用户是不可见的(因为子类访问权限为private),减轻了用户的负担(软件开发的根本目的之一,软件使生活更简单)。3. 抽象函数ComputeSalay()计算员工薪资。利用多态,客户端不必知道薪资计算方法,甚至不必知道员工类型,只要知道员工类有一个ComputeSalay方法可以计算薪资。4. Salay类的使用。薪资参与什么样的数据类型表示?可能是整型,可能是double,但是单位呢?可能是人民币,可能是美元。这种选择不是程序员能够

14、做出决定的,而是根据实际情况变动的。因此将其封装成类是明智的选择,在类中可以用整数表示美元,用属性表示等价的其他货币表示,总之,需求如果出现变动,可以安全的修改Salay类与其用户,然后如果原本只采用double表示薪资,后果是可怕的。考虑到Salay不可变的特性(其只是薪资数据的一个数据结构),采用struct实现更为合适。5. ItextDisplayable接口设计。接口的设计目标主要有两点,减轻用户负担、包含数据安全性。接口表示一种功能,然而调用此项功能的用户没有必要知道它还具备其他什么属性,甚至不必知道它是什么类的对象,这里的ItextDisplayable接口只用于提供输出,因此可

15、以放心的将类对象以接口的形式传递给界面层,不用担心内部数据的破坏,界面层也开开心心的使用,无知而幸福(MF)。3. 部门类设计部分代码展示:/ <summary> / 部门类,用于存储员工的集合。 / </summary> public class Department / <summary> / 创建一个部门实例,初始雇员集合为空 / </summary> public Department() Employees = new List<Employee>(); / <summary> / 获取或设置当成操作中的部门对象

16、 / </summary> public static Department CurDepartment get; set; / <summary> / 雇员集合 / </summary> private List<Employee> Employees; / <summary> / 获取部门中雇员的数量 / </summary> public int EmployeeCount get return this.Employees.Count; / <summary> / 向部门雇员列表中添加员工 / <

17、/summary> public void AddEmployee(Employee staff) if (staff != null) this.Employees.Add(staff); / <summary> / 删除雇员列表中的特定成员 / </summary> / <param name="staff">雇员对象</param> public bool RemoveEmployee(Employee staff) return this.Employees.Remove(staff); / <summar

18、y> / 删除雇员列表中的特定成员 / </summary> / <param name="name">雇员姓名</param> public bool RemoveEmployee(string name) return this.RemoveEmployee(GetEmployee(name); / <summary> / 在部门的雇员列表中查询指定姓名的雇员 / </summary> / <param name="name">雇员姓名</param> / &l

19、t;returns>如果存在,返回雇员的引用,如果不存在,返回null</returns> public Employee GetEmployee(string name) if (name = null | !this.Employees.Exists(o=>o.Name.CompareTo(name) = 0) return null; return this.Employees.Find(o => o.Name.CompareTo(name) = 0); / <summary> / 获取雇员集合的可显示接口集合 / </summary>

20、; public List<ITextDisplayable> EmployeesTranscript get List<ITextDisplayable> assemble = new List<ITextDisplayable>(); foreach (var item in this.Employees) assemble.Add(item); return assemble; / <summary> / 计算次部门当前所有员工的薪资之和 / </summary> public Salay ComputeTotalSalay()

21、 Salay money = new Salay(0); foreach (var employee in this.Employees) money = money.AppendDollars(employee.ComputeSalay().Dollars); return money; / <summary> / 根据雇员的薪资进行排序 / </summary> public void SortBySalay() this.Employees.Sort(); 1. List泛型的使用。现今面向对象程序设计语言的泛型模板封装了各种实用的数据结构,能够熟练使用它们是明智

22、的选择。这里,用List泛型表示员工的集合,内部的数据结构可能是链表,也可能是其他,我不知道也不必知道,这也是泛型模板带给开发者的好处。(有人说这样是傻瓜式的开发,我认为恰恰相反,因为这样的数据结构任何一个有参考书的傻瓜都可以实现,然而模板或编程环境将一些傻瓜式的细节帮我们省略了,让我们可以用更多的精力去做聪明的事情。机器生产的代码程序员也可以完成,至少程序员志存高远,应该担当软件开发的重任,这些基本的东西,交给计算机就可以了。)2. CurDepartment属性设计。这项属性的设计完全是被现实所迫,任务要求编写一个员工管理系统,却只做如此简单的需求说明,我只能临时设置一个类成员,用于全局共

23、享。如果有详细的需求说明,我会实现一个资源管理类,也可能只是传递引用,具体怎样设计取决于实际情况,由于我不想让程序变得复杂,所以就这样设计了。不用担心,未来完全可以通过重构将属性删去,改为想要的结果。3. ComputeTotalSalay方法计算薪资之后。正如员工类设计时候的说明,这里的薪资计算只需遍历集合并收集数据就可以了,这是一种隐藏,给人一种每个方法的设计和功能都非常简单易懂的感觉,软件开发就是要这样!4. 返回集合副本。之前有个方法返回员工集合的副本,之所以这样设计,是为了保护数据成员。因为C#和java的对象是按引用传递的,被传递出去的对象的可以被修改的(修改数据成员)。如果需求中

24、就需要被修改,考虑可以传递接口,只规定可被容许的修改并被负责任的类使用,仍然是安全的。5. 委托与委托链。在实现薪资排序的方法的时候,部门类委托List泛型类进行排序,而List泛型类会继续委托Icomparable接口提供的方法进行排序比较,而我员工类的Icomparable接口实现也是委托基础数据类型的比较方法。这样一层一层的委托隐藏了委托链,这在面向对象设计中极具价值。它让一个方法去真正负责它应负责的任务,不要多此一举、画蛇添足。当然,过多的委托也可能会产生坏味道,这时可以公布委托链,让用户直接与成员对话。6. 注释与代码可读性。我一般只对成员进行文档注释,说明字段或方法的含义和功能,很少对方法内容实现进行注释,因为我很少发现有这个必要,良好的命名和代码结构帮助我快速理解一个方法的功能。相反,有注释的地方往往意味着存在问题,因为程序员不得不用注释而不是代码来说明意图。一个方法如果负责它不应该负责的任务,则会产生副作用或逻辑紊乱,使代码的维护变得困难,这样的软件的生命期注定是短暂的,甚至在没有诞生之前就会死亡。4. 类说明图四 单元测试利用VS2010的单元测试框架对Department的重要函数功能进行了测试:五、设计总结顺应课题

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论