diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..40e0cfb9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +./.idea/* +./.idea diff --git a/LowLevelDesignConcepts.iml b/LowLevelDesignConcepts.iml new file mode 100644 index 00000000..ea1542ad --- /dev/null +++ b/LowLevelDesignConcepts.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/oops/SOLID/lsp/stack/before/IStack.java b/src/oops/SOLID/lsp/stack/before/IStack.java new file mode 100644 index 00000000..5b23c0fb --- /dev/null +++ b/src/oops/SOLID/lsp/stack/before/IStack.java @@ -0,0 +1,8 @@ +package oops.SOLID.lsp.stack.before; + +public interface IStack { + void push(T i); + void pop(); + T top(); + void clear(); +} diff --git a/src/oops/SOLID/lsp/stack/before/StackWrong.java b/src/oops/SOLID/lsp/stack/before/StackWrong.java index 1170e573..9b83e6a9 100644 --- a/src/oops/SOLID/lsp/stack/before/StackWrong.java +++ b/src/oops/SOLID/lsp/stack/before/StackWrong.java @@ -1,42 +1,51 @@ package oops.SOLID.lsp.stack.before; import java.util.ArrayList; +import java.util.List; + /* * Stack is-a list with push() pop() methods. * So can we create a stack by extending an ArrayList class? - * + * * No! This implementation violates the Liskov Substitution Principle. - * Which states that + * Which states that * "Objects in a program should be replaceable with instances of their subtypes * without altering the correctness of that program." - * + * * In this case ArrayList has multiple methods which stack is not supposed to have (ex clear(), get(i) etc) - * so objects of ArrayList are not fully replaceable by the objects of stack. - * + * so objects of ArrayList are not fully replaceable by the objects of stack. + * */ -public class StackWrong extends ArrayList{ - private int topPointer = 0; - - public void push(Integer a) { - add(topPointer, a); - topPointer++; - } - public void pop() { - remove(topPointer-1); - topPointer--; - } - public Integer top() { - return get(topPointer-1); - } - - public static void main(String[] args) { - StackWrong st = new StackWrong(); - st.push(1); - st.push(2); - System.out.println(st.top()); - st.pop(); - System.out.println(st.top()); - st.clear(); - System.out.println(st.top()); - } +public class StackWrong implements IStack { + private int topPointer = 0; + private List list = new ArrayList<>(); + + public void push(Integer a) { + list.add(topPointer, a); + topPointer++; + } + + public void pop() { + list.remove(topPointer - 1); + topPointer--; + } + + public Integer top() { + return list.get(topPointer - 1); + } + + public void clear() { + list.clear(); + } + + public static void main(String[] args) { + IStack st = new StackWrong(); + st.push(1); + st.push(2); + System.out.println(st.top()); + st.pop(); + System.out.println(st.top()); + st.clear(); + System.out.println(st.top()); + } } diff --git a/src/oops/SOLID/openClosePrinciple/before/client/CalculateTaxesClient.java b/src/oops/SOLID/openClosePrinciple/before/client/CalculateTaxesClient.java index 1651161c..ae732b68 100644 --- a/src/oops/SOLID/openClosePrinciple/before/client/CalculateTaxesClient.java +++ b/src/oops/SOLID/openClosePrinciple/before/client/CalculateTaxesClient.java @@ -26,10 +26,10 @@ public static void main(String[] args) { for (Employee employee: employees){ // compute individual tax - double tax = TaxCalculator.calculate(employee); + double tax = employee.calculateTax(); String formattedTax = currencyFormatter.format(tax); // add to company total taxes - totalTaxes += TaxCalculator.calculate(employee); + totalTaxes += employee.calculateTax(); } } } diff --git a/src/oops/SOLID/openClosePrinciple/before/employees/Employee.java b/src/oops/SOLID/openClosePrinciple/before/employees/Employee.java index a84b72a3..8d1cf425 100644 --- a/src/oops/SOLID/openClosePrinciple/before/employees/Employee.java +++ b/src/oops/SOLID/openClosePrinciple/before/employees/Employee.java @@ -57,5 +57,7 @@ public void setNbHoursPerWeek(int nbHoursPerWeek) { public String getFullName(){ return this.firstName + " " + this.lastName; } + + public abstract double calculateTax(); } diff --git a/src/oops/SOLID/openClosePrinciple/before/employees/FullTimeEmployee.java b/src/oops/SOLID/openClosePrinciple/before/employees/FullTimeEmployee.java index cd9e9384..151428bc 100644 --- a/src/oops/SOLID/openClosePrinciple/before/employees/FullTimeEmployee.java +++ b/src/oops/SOLID/openClosePrinciple/before/employees/FullTimeEmployee.java @@ -1,8 +1,17 @@ package oops.SOLID.openClosePrinciple.before.employees; +import oops.SOLID.openClosePrinciple.before.taxes.FullTimeEmployeeTaxCalculator; +import oops.SOLID.openClosePrinciple.before.taxes.TaxCalculator; + public class FullTimeEmployee extends Employee { public FullTimeEmployee(String fullName, int monthlyIncome) { super(fullName, monthlyIncome); this.setNbHoursPerWeek(40); } + + @Override + public double calculateTax() { + TaxCalculator taxCalculator = new FullTimeEmployeeTaxCalculator(); + return taxCalculator.calculate(this); + } } diff --git a/src/oops/SOLID/openClosePrinciple/before/employees/Intern.java b/src/oops/SOLID/openClosePrinciple/before/employees/Intern.java index 80191de2..4c740ea0 100644 --- a/src/oops/SOLID/openClosePrinciple/before/employees/Intern.java +++ b/src/oops/SOLID/openClosePrinciple/before/employees/Intern.java @@ -1,8 +1,17 @@ package oops.SOLID.openClosePrinciple.before.employees; +import oops.SOLID.openClosePrinciple.before.taxes.InternTaxCalculator; +import oops.SOLID.openClosePrinciple.before.taxes.TaxCalculator; + public class Intern extends Employee { public Intern(String fullName, int monthlyIncome, int nbHours) { super(fullName, monthlyIncome); setNbHoursPerWeek(nbHours); } + + @Override + public double calculateTax() { + TaxCalculator taxCalculator = new InternTaxCalculator(); + return taxCalculator.calculate(this); + } } diff --git a/src/oops/SOLID/openClosePrinciple/before/employees/PartTimeEmployee.java b/src/oops/SOLID/openClosePrinciple/before/employees/PartTimeEmployee.java index 5c491175..1c139c0a 100644 --- a/src/oops/SOLID/openClosePrinciple/before/employees/PartTimeEmployee.java +++ b/src/oops/SOLID/openClosePrinciple/before/employees/PartTimeEmployee.java @@ -1,8 +1,17 @@ package oops.SOLID.openClosePrinciple.before.employees; +import oops.SOLID.openClosePrinciple.before.taxes.PartTimeEmployeeTaxCalculator; +import oops.SOLID.openClosePrinciple.before.taxes.TaxCalculator; + public class PartTimeEmployee extends Employee { public PartTimeEmployee(String fullName, int monthlyIncome) { super(fullName, monthlyIncome); this.setNbHoursPerWeek(20); } + + @Override + public double calculateTax() { + TaxCalculator taxCalculator = new PartTimeEmployeeTaxCalculator(); + return taxCalculator.calculate(this); + } } \ No newline at end of file diff --git a/src/oops/SOLID/openClosePrinciple/before/taxes/FullTimeEmployeeTaxCalculator.java b/src/oops/SOLID/openClosePrinciple/before/taxes/FullTimeEmployeeTaxCalculator.java new file mode 100644 index 00000000..b9b2945c --- /dev/null +++ b/src/oops/SOLID/openClosePrinciple/before/taxes/FullTimeEmployeeTaxCalculator.java @@ -0,0 +1,17 @@ +package oops.SOLID.openClosePrinciple.before.taxes; + +import oops.SOLID.openClosePrinciple.before.employees.Employee; +import oops.SOLID.openClosePrinciple.before.employees.FullTimeEmployee; + +public class FullTimeEmployeeTaxCalculator implements TaxCalculator { + private static final Integer INCOME_TAX = 30; + private static final Integer PROFESSIONAL_TAX = 2; + private static final Integer EDUCATION_CESS = 1; + + @Override + public double calculate(FullTimeEmployee employee) { + Integer income = employee.getMonthlyIncome(); + return income * INCOME_TAX / 100 + income * PROFESSIONAL_TAX / 100 + + income * EDUCATION_CESS / 100; + } +} diff --git a/src/oops/SOLID/openClosePrinciple/before/taxes/InternTaxCalculator.java b/src/oops/SOLID/openClosePrinciple/before/taxes/InternTaxCalculator.java new file mode 100644 index 00000000..2dd2b12d --- /dev/null +++ b/src/oops/SOLID/openClosePrinciple/before/taxes/InternTaxCalculator.java @@ -0,0 +1,15 @@ +package oops.SOLID.openClosePrinciple.before.taxes; + +import oops.SOLID.openClosePrinciple.before.employees.Intern; + +public class InternTaxCalculator implements TaxCalculator { + @Override + public double calculate(Intern employee) { + Integer income = employee.getMonthlyIncome(); + if (income < 300000) { + return 0; + } else { + return income * 15 / 100; + } + } +} diff --git a/src/oops/SOLID/openClosePrinciple/before/taxes/PartTimeEmployeeTaxCalculator.java b/src/oops/SOLID/openClosePrinciple/before/taxes/PartTimeEmployeeTaxCalculator.java new file mode 100644 index 00000000..6d8c3a89 --- /dev/null +++ b/src/oops/SOLID/openClosePrinciple/before/taxes/PartTimeEmployeeTaxCalculator.java @@ -0,0 +1,17 @@ +package oops.SOLID.openClosePrinciple.before.taxes; + +import oops.SOLID.openClosePrinciple.before.employees.Employee; +import oops.SOLID.openClosePrinciple.before.employees.PartTimeEmployee; + +public class PartTimeEmployeeTaxCalculator implements TaxCalculator { + private static final Integer INCOME_TAX = 20; + private static final Integer PROFESSIONAL_TAX = 3; + private static final Integer EDUCATION_CESS = 1; + + @Override + public double calculate(PartTimeEmployee employee) { + Integer income = employee.getMonthlyIncome(); + return income * INCOME_TAX / 100 + income * PROFESSIONAL_TAX / 100 + + income * EDUCATION_CESS / 100; + } +} diff --git a/src/oops/SOLID/openClosePrinciple/before/taxes/TaxCalculator.java b/src/oops/SOLID/openClosePrinciple/before/taxes/TaxCalculator.java index ab0300be..df3c7265 100644 --- a/src/oops/SOLID/openClosePrinciple/before/taxes/TaxCalculator.java +++ b/src/oops/SOLID/openClosePrinciple/before/taxes/TaxCalculator.java @@ -2,15 +2,6 @@ import oops.SOLID.openClosePrinciple.before.employees.Employee; -public class TaxCalculator { - private final static int INCOME_TAX_PERCENTAGE = 20; - private final static int PROFESSIONAL_TAX_PERCENTAGE = 3; - - - public static double calculate(Employee employee) { - return - (employee.getMonthlyIncome() * PROFESSIONAL_TAX_PERCENTAGE) / 100 + - (employee.getMonthlyIncome() * INCOME_TAX_PERCENTAGE) / 100; - - } +public interface TaxCalculator { + double calculate(T employee); } \ No newline at end of file diff --git a/src/oops/SOLID/singleResponsibilityPrinciple/before/Employee.java b/src/oops/SOLID/singleResponsibilityPrinciple/before/Employee.java index a742fac0..173cb9e2 100644 --- a/src/oops/SOLID/singleResponsibilityPrinciple/before/Employee.java +++ b/src/oops/SOLID/singleResponsibilityPrinciple/before/Employee.java @@ -14,7 +14,7 @@ public abstract class Employee { private int monthlyIncome; private int nbHoursPerWeek; - public Employee(String fullName, int monthlyIncome){ + public Employee(String fullName, int monthlyIncome) { setMonthlyIncome(monthlyIncome); String[] names = fullName.split(" "); @@ -40,7 +40,7 @@ public int getMonthlyIncome() { } public void setMonthlyIncome(int monthlyIncome) { - if(monthlyIncome < 0){ + if (monthlyIncome < 0) { throw new IllegalArgumentException("Income must be positive"); } @@ -52,43 +52,33 @@ public int getNbHoursPerWeek() { } public void setNbHoursPerWeek(int nbHoursPerWeek) { - if(nbHoursPerWeek <= 0){ + if (nbHoursPerWeek <= 0) { throw new IllegalArgumentException("Income must be positive"); } this.nbHoursPerWeek = nbHoursPerWeek; } - public String getFullName(){ + public String getFullName() { return this.firstName + " " + this.lastName; } - public void save(){ - try { - Employee employee =this; - StringBuilder sb = new StringBuilder(); - sb.append("### EMPLOYEE RECORD ####"); - sb.append(System.lineSeparator()); - sb.append("NAME: "); - sb.append(employee.firstName + " " + employee.lastName); - sb.append(System.lineSeparator()); - sb.append("POSITION: "); - sb.append(employee.getClass().getTypeName()); - sb.append(System.lineSeparator()); - sb.append("EMAIL: "); - sb.append(employee.getEmail()); - sb.append(System.lineSeparator()); - sb.append("MONTHLY WAGE: "); - sb.append(employee.monthlyIncome); - sb.append(System.lineSeparator()); - - Path path = Paths.get(employee.getFullName() - .replace(" ","_") + ".rec"); - Files.write(path, sb.toString().getBytes()); - - System.out.println("Saved employee " + employee.toString()); - } catch (IOException e){ - System.out.println("ERROR: Could not save employee. " + e); - } + public String serializeData() { + StringBuilder sb = new StringBuilder(); + sb.append("### EMPLOYEE RECORD ####"); + sb.append(System.lineSeparator()); + sb.append("NAME: "); + sb.append(this.getFullName()); + sb.append(System.lineSeparator()); + sb.append("POSITION: "); + sb.append(this.getClass().getTypeName()); + sb.append(System.lineSeparator()); + sb.append("EMAIL: "); + sb.append(this.getEmail()); + sb.append(System.lineSeparator()); + sb.append("MONTHLY WAGE: "); + sb.append(this.getMonthlyIncome()); + sb.append(System.lineSeparator()); + return sb.toString(); } } diff --git a/src/oops/SOLID/singleResponsibilityPrinciple/before/EmployeeRepository.java b/src/oops/SOLID/singleResponsibilityPrinciple/before/EmployeeRepository.java index b76f4589..66301c83 100644 --- a/src/oops/SOLID/singleResponsibilityPrinciple/before/EmployeeRepository.java +++ b/src/oops/SOLID/singleResponsibilityPrinciple/before/EmployeeRepository.java @@ -1,5 +1,9 @@ package oops.SOLID.singleResponsibilityPrinciple.before; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Arrays; import java.util.List; @@ -16,4 +20,20 @@ public List findAll(){ return Arrays.asList(anna, billy, steve, magda); } + + public void save(Employee employee){ + try { + String employeeData = employee.serializeData(); + + Path path = Paths.get(employee.getFullName() + .replace(" ","_") + ".rec"); + Files.write(path, employeeData.getBytes()); + + System.out.println("Saved employee " + employee.toString()); + } catch (IOException e){ + System.out.println("ERROR: Could not save employee. " + e); + } + } + + } \ No newline at end of file