Assignment 1 – Refactoring
Contents
Identification of smells in original code……………………………………………………….1
EA Class Diagram………………………………………………………………………………9
GitHub Repository Link……………………………………………………………………...10
Code after refactoring………………………………………………………………………...10
Identification of smells in original code
public enum AnimalType {
Insured, Uninsured
}
public enum Type {
Veterinarian,InsuredAnimal,Animal
}
public class Animal {
public Veterinarian assignedVeterinarian=null; // Veterinarian assigned to Animal
private static int pIdNo = 100000; // No get and set methods - internal use only
private String name;
private String identifier; // Animal identifier - unique for each animal in the system
public AnimalType animalType= AnimalType.Uninsured; // can be "Insured" or "Uninsured" - Uninsured should be "default"
private String preferredVeterinarian=null; // Only useful for "Insured" - null for Uninsured animal
private String insuredHealthFundNo; // Fund number for animals with insured health
private int hoursTreated; // No of hours animal treated by Veterinarian
public Animal()
{
assignedVeterinarian = null;
this.SetIdentifier();
this.preferredVeterinarian = null;
this.insuredHealthFundNo = null;
}
public Animal(String name, int age, int hoursTreated, String aBreed){ // constructor to create an uninsured animal
this();
this.name = name;
this.hoursTreated = hoursTreated;
}
public Animal(String name, int age, AnimalType animalType, String preferredVeterinarian, String insuredHealthFundNo, int hoursTreated, String aBreed){ //create insured animal
this(name,age, hoursTreated, aBreed);
this.animalType = animalType;
this.preferredVeterinarian = preferredVeterinarian;
this.insuredHealthFundNo = insuredHealthFundNo;
}
public final boolean assignVeterinarian(ArrayList
listOfVeterinarians){
if (animalType == AnimalType.Insured)
isPreferredVeterinarian(listOfVeterinarians);
else if (animalType == AnimalType.Uninsured)
isMax(listOfVeterinarians);
return false;
}
public final String getName(){
return name;
}
public boolean isPreferredVeterinarian(ArrayList listOfVeterinarians)
{
for (int i = 0; i < listOfVeterinarians.size(); i++){
Veterinarian temp = (Veterinarian)listOfVeterinarians.get(i);
if (this.preferredVeterinarian.equals(temp.name)){ // is this the preferred vet?
if (temp.listOfAnimals.size() < temp.maxNumOfAnimals){ // allocate animal to this vet - if possible
assignedVeterinarian = temp;
temp.listOfAnimals.add(this);
return true;
}
else // that preferred vet has no capacity for new animals on their list, need to find another vet at this clinic
{
int vets = listOfVeterinarians.size();
mvToANewVet (this.animalType);
for (int ii = 0; ii < vets; ii++){ // choose which vet to allocate - find a vet with room left in list of registered animals
Veterinarian temp2 = (Veterinarian)(listOfVeterinarians.get(ii));
if (temp2.listOfAnimals.size() < temp2.maxNumOfAnimals){
temp2.listOfAnimals.add(this);
System.out.println("Allocating "+ this.getName() + " to " + temp2.name + "\n");
this.assignedVeterinarian = temp2;
return true;
}
}
}
}
}
return false;
}
public boolean isMax(ArrayList listOfVeterinarians)
{
for (int i = 0; i < listOfVeterinarians.size(); i++){ // choose which vet to allocate - search for a vet at this clinic with room left in list of registered animals
Veterinarian temp = (Veterinarian)(listOfVeterinarians.get(i));
if (temp.listOfAnimals.size() < temp.maxNumOfAnimals){
temp.listOfAnimals.add(this);
this.assignedVeterinarian = temp;
return true;
}
}
return false;
}
public final String mvToANewVet (AnimalType animalInsuranceType){
String output = "";
switch(animalInsuranceType) {
case Uninsured:
output += "Assigning uninsured animal " + this.name + " to the waiting list until a veterinarian becomes available somewhere\n";
break;
case Insured:
output += "Preferred Veterinarian unavailable. Reassigning Insured Animal " + this.name + " to a different Vet at this clinic\n";
break;
}
System.out.print(output);
return output;
}
public final String mv(AnimalType animalInsuranceType){
String output = "";
switch(animalInsuranceType) {
case Uninsured:
output += "Will need to assign uninsured animal " + this.name + " to the waiting list until a veterinarian becomes available\n";
break;
case Insured:
output += "Will need to reassign Insured Animal " + this.name + " to a different clinic\n";
}
System.out.print(output);
return output;
}
public final void SetIdentifier(){
this.identifier = "P" + pIdNo++;
}
public String toString(){
String output1= "", output2="";
String result = "";
switch(animalType) {
case Uninsured:
output1 = "Uninsured Animal - " + this.name + "\n\t Identifier: " + this.identifier + "\n\t Assigned Veterinarian: ";
if (this.assignedVeterinarian == null)
output2 = "not assigned as yet";
else
output2 = this.assignedVeterinarian.name + "\n\t Fee for "+ this.hoursTreated + " hours consultation = $" + this.hoursTreated * this.assignedVeterinarian.getHourlyRate();
break;
case Insured:
output1 = "Insured Animal - " + this.name + "\n\t Identifier: " + this.identifier + "\n\t Preferred Veterinarian: " + this.preferredVeterinarian + "\n\t Insured Health Fund Number: " + this.insuredHealthFundNo +
"\n\t Assigned Veterinarian: ";
if (this.assignedVeterinarian == null)
output2 = "not assigned as yet";
else
output2 = this.assignedVeterinarian.name + "\n\t Fee for "+ this.hoursTreated + " hours consultation = $" + this.hoursTreated * this.assignedVeterinarian.getHourlyRate();
break;
}
result = output1 + output2 + "\n";
return result;
}
}
public class Veterinarian {
private String specialisation; // Veterinarian's special skill
public ArrayList listOfAnimals; // Veterinarian's personal list of animals responsible for care
public int maxNumOfAnimals; // Maximum no. of animals a Veterinarian can have at one time
private double hourlyRate; // Hourly rate of pay
private static int vetIdNo = 1000; // Internal use only - no get/set methods
public String name; // Name of Veterinarian
private String identifier; // Veterinarian's staff id
public final boolean HasAnimals(){ // does the Vet have any animals registered for care?
return !listOfAnimals.isEmpty();
}
public Veterinarian(){ // constructor to set up a Veterinarian object
specialisation = "Unknown";
listOfAnimals = new ArrayList(); // initially no animals registered
listOfAnimals.clear();
maxNumOfAnimals = 0; // maximum number of animals that can be registered to the Vet
hourlyRate = 100;
this.setIdentifier();
}
public Veterinarian(String name, int age, int animals2, String specialisation){
this();
this.name = name;
maxNumOfAnimals = animals2;
this.specialisation = specialisation;
}
public Veterinarian(String name, int age, int animals2, String specialisation, double hourlyRate){
this(name, age,animals2,specialisation);
this.hourlyRate = hourlyRate;
}
public String toString(){
return "*******************\n Dr " + this.name + "\n\t id number: " +
identifier +
"\n\t Max Number of Patients: " + this.maxNumOfAnimals;
}
public double getHourlyRate(){
return this.hourlyRate;
}
public String printListOfAnimals(){
String temp = "";
temp += "\nList of Animals registered for Dr " + this.name + "\n\n";
for (int i = 0; i < this.listOfAnimals.size(); i++){
temp += ((Animal) this.listOfAnimals.get(i)) + "\n";
}
return temp;
}
public void setIdentifier(){
this.identifier = "V" + String.valueOf(vetIdNo++);
}
}
public class MainDriverClass {
public static final String OUTPUT_FILE = "MyOutput.txt";
public static final String TEST_FILE = "MyTest.txt";
public static void main(String[] args) {
MainDriverClass mdc = new MainDriverClass();
mdc.printing();
}
public void printing()
{
try
{
String outputString = new Clinic().run();
System.out.println(outputString);
BufferedWriter writer = new BufferedWriter(new FileWriter(OUTPUT_FILE));
writer.write(outputString);
writer.close();
}
catch(IOException ioe)
{
System.out.println("Error Message: "+ioe);
}
}
}
We can break the code, and removed unused attributes, removing if-else condition, we make better to extends in future
EA Class Diagram:
(Before)
After
GitHub Repository Link:
https://github.com/ITECH2309feduni/assignment-1-201917-refactoring-manjinderingh.git
Code after refactoring
assignment-1-201917-refactoring-manjinderingh-master.zip
assignment-1-201917-refactoring-manjinderingh-master/ITECH2309_2019/.classpath
assignment-1-201917-refactoring-manjinderingh-master/ITECH2309_2019/.gitignore
/bin/
assignment-1-201917-refactoring-manjinderingh-master/ITECH2309_2019/.project
ITECH2309_2019
org.eclipse.jdt.core.javabuilder
org.eclipse.jdt.core.javanature
assignment-1-201917-refactoring-manjinderingh-master/ITECH2309_2019/.settings/org.eclipse.jdt.core.prefs
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8
assignment-1-201917-refactoring-manjinderingh-master/ITECH2309_2019/MyInput.csv
Veterinarian,Ben Casey,32,3,Small Animals,,
Veterinarian,Hawkeye Pierce,47,3,Large Animals,,
Veterinarian,Doogie Howser,22,1,Horses,,
InsuredAnimal,Fred Bear,2,Ben Casey,HCF236788,10, Cockerspaniel
Animal,Betty Bird,3,7,Budgerigar,,
InsuredAnimal,Bella Plant,3,Ben Casey,HCF265123,23, Rabbit
InsuredAnimal,Dagwood Dog,8,Doogie Howser,HCF265988,2, Labrador
InsuredAnimal,Ernie,2,Ben Casey,HCF134231,1, Guinea Pig
Animal,Tinkerbell,4,1,Siamese cat,,
Animal,Slinky,1,1,Blue Tongue Lizard,,
InsuredAnimal,Mickey Mouse,5,Ben Casey,HCF234511,1, Mouse
assignment-1-201917-refactoring-manjinderingh-master/ITECH2309_2019/MyOutput.txt
___________________
List of registered veterinarians
___________________
*******************
Dr Ben Casey
...