java - Refactoring code to be Generics and functional interface -
i have 2 interfaces 1 can used find statistics key , value , other used visit object , iterate on it, first 1 has following methods:
public interface statistic { public string getkey(); public object getvalue(); public string getdetails(); } and here implementation it:
public class collector implements statistic { private string key; private int val; public collector(string key, int val) { this.key = key; this.val = val; } public void setvalue(int val) { this.val = val; } @override public string getkey() { return key; } @override public integer getvalue() { return val; } @override public string getdetails() { return null; } } and other 1 has following:
public interface statisticscollector<t extends object, s extends statistic> { public string getname(); public void visit(t object); public iterator<s> calculatedstatistics(); } and here implementation it:
public class calculatefromobject<k, v> implements statisticscollector<object, collector> { employeevalidator empvalidator = new employeevalidator(); stringvalidator strvalidator = new stringvalidator(); @override public string getname() { return null; } @override public void visit(object object) { if (object instanceof string) { string str = object.tostring(); int uppercasecount = strvalidator.uppercasefreq(str); strvalidator.set.add(new collector("upper case letters: ", uppercasecount)); int lowercasecount = strvalidator.lowercasefreq(str); strvalidator.set.add(new collector("lower case letters: ", lowercasecount)); int digitscount = strvalidator.digitfreq(str); strvalidator.set.add(new collector("digits count: ", digitscount)); int wordcount = strvalidator.wordfreq(str); strvalidator.set.add(new collector("words count: ", wordcount)); int nonwordcount = strvalidator.nonwordfreq(str); strvalidator.set.add(new collector("non word count: ", nonwordcount)); } else if (object instanceof employee) { employee emp = (employee) object; empvalidator.salaryvalidator(emp); empvalidator.birthdatevalidator(emp); empvalidator.birthplacevalidator(emp); empvalidator.resignationdatevalidator(emp); empvalidator.positionvalidator(emp); } } @override public iterator<collector> calculatedstatistics() { return empvalidator.set.iterator(); } } and in package have bean employee has few properties firstname, lastname, salary , position setters , getters.
i validations me number of employees has salary of x , been born in 1990 , did following class these validations:
public class employeevalidator { public set<collector> set = new hashset<>(); public void salaryvalidator(employee emp) { int count = 0; // each collector consist of condition (function), key, value (always incremented) if (emp.getsalary() < 350) { set.add(new collector("employee salaries less 350jd: ", ++count)); } else if (emp.getsalary() >= 350 && emp.getsalary() < 600) { set.add(new collector("employee salaries between 350jd , 600jd: ", ++count)); } else if (emp.getsalary() >= 600 && emp.getsalary() < 1200) { set.add(new collector("employee salaries between 600jd , 1200jd ", ++count)); } else if (emp.getsalary() >= 1200) { set.add(new collector("employee salaries more 1200jd: ", ++count)); } } public void birthdatevalidator(employee emp) { (collector stats : set) { if (("employees born in " + emp.getbirthdate().getyear() + " = ").equals(stats.getkey())) { count(stats); return; } } set.add(new collector("employees born in " + emp.getbirthdate().getyear() + " = ", 1)); } public void birthplacevalidator(employee emp) { (collector stats : set) { if (("employees born in " + emp.getbirthplace() + " = ").equals(stats.getkey())) { count(stats); return; } } set.add(new collector("employees born in " + emp.getbirthplace() + " = ", 1)); } public void resignationdatevalidator(employee emp) { (collector stats : set) { if (("employees resignation in " + emp.getresignationdate().getyear() + " = ").equals( stats.getkey())) { count(stats); return; } } set.add(new collector("employees resignation in " + emp.getresignationdate().getyear() + " = ", 1)); } public void positionvalidator(employee emp) { (collector stats : set) { if (("employees occupy " + emp.getposition() + " position = ").equals(stats.getkey())) { count(stats); return; } } set.add(new collector("employees occupy " + emp.getposition() + " position = ", 1)); } private void count(collector stats) { int counter = stats.getvalue() + 1; stats.setvalue(counter); } } and have class validate strings , see how many uppercase letters string has, how many lower case has...etc
as can see in visit method in calculatefromobject class im calling methods validations, working fine , getting expected results, code not efficient make generic , make accept type of object, have done few tries im stuck.
i have tried write functional interface called conditions has 1 method can pass condition , check following:
public interface conditions { boolean checkcondition(object obj); } so can suggest best way change code generic , accept type of objects student example , clean possible maybe applying design pattern?
there's lot of overhead in classes , misunderstanding of interfaces against pojo's (simple classes). on high level should following:
1). remove interface statistic , class collectors. incapsulating data. instead - create pojo employee necessary fields + getters + setters. don't use 'key-value`, give fields meaningful names:
public class employee { private string name; private int id; private double salary; ... public string getname() {...} public void setname(..) {...} // other getters / setters } create constructor if needed
2) looks employee class redundant, remove it. use new employee instead 3) use collections framework store collections of employee's instances.
`list<employee> employees = new arraylist<>(); employees.add(new employee(.... )); ` 4). create interface employeevalidator validating methods , implement it:
public interface employeevalidator { void validate(list<employee> employees); }
5) if want operate statistics data, create separate statistics class operate on collections of employees, e.g.
public class statistics { public double getavgsalary(list<employee> employees) { double avgsalary = 0; (employee e : employees) { .... } } }
Comments
Post a Comment