![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
MP8Homework 8. Payroll revisited againPart 1.Change class Employee to use ValueWithHistory (use parcel "CS598rej-ValueWHistory" at the bottom of this page) to store values that change over time. You won't use it to store the name of the Employee or its set of transactions, but you can use it for just about everything else. This will permit old transactions to work correctly even if a salary change or something similar has occurred.You will have to change the initialization method to initialize the Employee properly. Then you'll have to change every place you read the variable to use #at:, every place you assign to the variable to use #starting: become:, and every place you increment the variable to use #at: add:. You can use as a starting point the sample solution for Homework 5. Also it makes sense to change the accessing methods in Employee to reflect the value with history usage (for instance change #earned to #earnedAt: aDate ). Define a method for Employee called salaryHistoryOn: aStream. It prints a report on aStream that gives the dates of all salary changes and what the new salary was. The report should follow this style:
We provided EmployeeTestCase for this part (found in parcel CS598rej - Testing Homework8 at the bottom). Make sure this passes before moving forward. Part 2. Adding Withholdings to the Payroll SystemExercise 2.1.So far, the payroll system only withholds taxes. Change it so that it can withhold insurance payments, too. You'll have to change the Paycheck class so that it records how much was withheld for insurance and prints it on a paycheck. You'll have to add a new instance variable to Employee to keep the total insurance payments withheld, and modify Employee>>makePaycheckAt: to compute the amount withheld so that it can be stored in the paycheck. Note that makePaycheckAt: does NOT change the Employee class. You don't update the totals in Employee when you create a Paycheck, but when you post it. Not everyone will have the same insurance payments. However, you can assume that each person has a fixed amount withdrawn from each paycheck. Make a transaction for changing this amount (call its class InsuranceChange). Next exercise will ask you to do lots of refactorings. Before moving forward, make sure that all the test cases in EmployeeTestCase and PayrollSystemTestCase (we provided them at the bottom of this page) pass. As you perform refactorings, running these tests should keep you confident that you did not break things. Exercise 2.2.
Wait! Isn't this just like the last problem? What if tomorrow you are asked to withhold donations to the United Way, and the day after that you are asked to withhold child support payments? It is common for an employer to withhold more than just taxes. The current design of the payroll system does not make it very easy to add a new kind of withholding. Moreover, it is unlikely that everybody would want to have the same withholdings. There needs to be a way to add a new withholding easily that also makes it easy for every employee to have a different set of withholdings. The standard trick to keep from having to add new instance variables is to use a Dictionary. An Employee would have an instance variable "withholders" that is a dictionary that maps strings (or, better yet, symbols) to numbers. To ask for taxes you would say (withholders at: #taxes). The Paycheck probably needs to have a dictionary that listed the withholdings too. There has to be some code to compute the withholdings for each paycheck. Different withholdings require different algorithms. The best way to let each Employee have a different set of algorithms is to make the algorithms into objects. There should be a Withholder class hierarchy. Each Withholder is able to take an employee and a paycheck, compute the amount to be withheld, and add it to the paycheck. Withholders will get used during makePaycheckAt: that will create the initial paycheck, initialize it with the date, employee, original amount and withholders, and then will pass the paycheck off to the Employee's withholders to have them compute the withholdings. Create an abstract method #withholdingOn: aCheck for:anEmployee at: aDate in class Withholder and let all its subclasses implement it. Step 1: Create a Withholder class and
one
subclass, TaxWithholder. A TaxWithholder
takes
a TaxRule, so there is no reason
for the Employee to have a TaxRule. Instead, it will have a collection
of Withholders. For the time being, it will have one for
taxes and one for insurance (call it InsuranceWithholder). Change makePaycheckAt:
to use the Withholders to compute the withholding. Make sure it
does what it does now. Move those methods in Employee that deal with
taxation to TaxWithholder. Step 2: Change Employee and Paycheck to use a dictionary to store the various kinds of withholdings. First change one, and test it, then change the other. Make sure it does what it does now before adding new kinds of withholdings. You'll have to change both postTo: in Paycheck and makePaycheckAt: in Employee. Step 3: We provided a test case (class Exercise22TestCase in parcel
CS598rej - Testing Homework8) that exercises adding a
RetirementWithholder. Make sure that it passes. EmployeeTestCase and PayrollSystemTestCase should still pass. In class
Exercise22TestCase we added some grading tests that check specific
implementation details. Make sure they pass as well. FilesCS598rej-Testing Homework8.stCS598rej-ValueWHistory.st AdviceWhile trying to import the ValueWithHistory class, I ran into some conflicts. If this happens to you, you will need to reload the original, unmodified Payroll system from HW2 and then reload the ValueWithHistory package above. The changes that you have to make for this exercise will also break all the previous test cases from the homework assignments. This is OK since your implementation for this homework will greatly change the structure of the payroll system. As many of you have pointed out on the MP8 discussion page, there are actually a lot of missing requirements for this assignment. A lot of methods are not being tested and there is no way to find out whether they are working or not since we do not have the test cases. This shows the importance of test cases (or at least a real list of requirements) which unfortunately we do not have. The instructions themselves also do not specify further requirements. Thus, I will only be grading you based on the tests themselves. Make sure that you have a proper WithHolder hierarchy and sublcasses (InsuranceWithholder, RetirementWithholder, TaxWithholder). Also make sure that you use the ValueWithHistory for the variables in Employee. DeliverablesSend me an e-mail with the changes that you have made using the standard Smalltalk notations that you have been using so far. Do not send me the entire PayrollSystem; it's really really hard to find out the changes that you have made. You should send me what you did for Part 1 and Part 2.2 (the final product). Do not worry about Part 2.1 since that is just an intermediate step. Link to this Page
|