OOP Design Question - oop

Got this interview question which i'm wondering about:
A software company designed an app that manages employees and, among other functions, calculates Salary.
The current structure which fits the customer's requirements is:
abstract Class Employee;
Class Manager extends Employee;
Class Engineer extends Employee;
The customer would now like to add the ability to support different types of salary calculations for employees who work on an hourly wage, monthly salary. Both Engineer and Manager can be either.
The customer also notified the software company that they will add a number of other types of salaries in the future.
The Question - How would you design this? Does if fall in any design pattern solution?
Thanks!

Apply the strategy pattern:
http://en.wikipedia.org/wiki/Strategy_pattern
Make "Salary_Calculation" a strategy associated to Employee. "Salary_Calculation" should be an interface or an abstract base class, and each salary calculation model is a subclass of that.

Add a SalaryCalculator interface and instantiate a SalaryCalculator object during the Employee object's construction using the salary type. The SalaryCalculaotr object will take care of salary calculations for each salary type.

Related

How to prevent a clutter of DTO objects?

I am using the DTO pattern,
I am using an Auto Mapper library to even help map domain objects to DTO objects and it works well.
now that my application gets bigger i find myself in need for many different DTO object supporting different data needs.
lets say for example my application displays a list of employees each employee has an age property and a salary property in my application.
in my UI, on one page i show just a list of all the employees, in a different one i show a list of departments names the employees are in and the number of employees in each one, on a different page i show statistics on each avg salary, avg age total employee salary in the department etc...
considering i have many departments and many employees (lets say millions of employees and thousands of departments, too many for the client to calculate statistics on its own)
my question is how would you build an API that serves the client without creating many many DTOs? and without making unnecessary calculations?
for example: in one flow counting the amount of employees in a department without calculating the avg salary in a case the avg salary is not interesting in order to make the api respond quicker and in another case calculating them both.
are there any other patterns to make this more efficient?
GraphQL is one potential option. It's a tool developed by Facebook for retrieving specific parts of their domain without retrieving the whole object.
This works well for retrieving pre-existing domain data. It doesn't work as well for calculating data (you mention count of employees and avg salary). As long as these are defined attributes (of department) you're fine.

Common lookup table and entity relationship questions

Second year CS student here.
Questions:
Is the 'Results' Table currently creating a 'common look-up table'?
How do I solve Employment-student relationship?
Database problem:
For each student they would like to know which degree program they were on (a student may have studies for more than one degree but not at the same time); the modules they took and their final results. For their employment they would like to know the type of employment (Full Time or Part Time, Permanent or Fixed Term, Continued Education, Taking gap year); their job title and whether it is considered a ‘Graduate’ role; The name and address of the employer; a contact email for the student, whether we can use that information for publicity purposes and a brief description of their role.
My current design for Database:
Current ERD
Q1.
I noticed when constructing the ERD there was a ternary relationship between Module, Degree and Student and decided to solve this many to many problem by creating a fourth table called results. It has foreign keys from Module, Degree and Student and contains the Result date and Result score for a student in a module on a degree. Considering each student takes several modules there will be a lot of entries, will 'Results' form a common look up table? I heard these were not best practise when constructing a DB. This design also makes it difficult to query which degrees each student has done (each student can take many degrees just not at the same time). I considered creating separate tables for the Student-Module relationship and Student-Degree relationship however you then would not know which module was taken under which degree.
Q2.
I was given this advice by my lecturer:
The relationship between employment and students it not quite clear and would require some explanation. Typically an employment in the real world is between 1 employer and 1 employee only, not multiple employees per employment.
Student-Employment Relationship
Is this a suitable fix? I currently have a foreign key in student which relates to their employment. Am i still able to use this or am i thinking about this relationship all wrong?
The database should support the following queries:
For a particular student their employment details
Details of students for which they do not have Employment records
Details of students who were unintentionally unemployed within 6 months of their graduation
% of students employed within one year of graduating according to class of degree
% of students in a graduate role for a particular year and degree program
All answers are greatly appreciated. Thanks for your time.

When to create a new table?

I have an application with employees and their work contracts.
Each work contract has a Vacation. We keep track of how many days the company owes the employee ("VacationOwe") and how many he has taken ("VacationTaken").
Should I make this "VacationOwe" and "VacationTaken" a property of the Contract, or should I create a class (table) called Vacaction with the properties "VacationOwe", "VacationTaken" and "ContractId" and join the two tables?
What are the advantange of both methods?
Is there any rule when you should create a new class or table or keep the data in one.
If the two properties are truly only related to an employee, there's no benefit of creating a separate table. Performance will be worse and you'll constantly have to join on those tables.
For this specific example, it seems like the vacation days may also be linked to a year. If that's the case, a separate table would make sense so you can track vacation days taken/owed by employee and year.
should I make this "VacationOwe" and "VacationTaken" a propertie o the employee
Most probably...No. Because this defeats normalization. Also, it does not provide information about when the vacations were taken (in case you care about that). In addition to that, you have to do this calculation for every employee, every year.
Use a class (table) Call Vacaction with properties "VacationOwe" and "VacationTaken" and "EmployeeId" and cross the two tables?
It is not good to have a singleton class in this case. In general you should avoid singletons in most cases.
So what to do? Well, if you system does not care about vacation details, you could go with the first solution. Maybe you want to consider option (A) below or If you would like to have a more generic approach you could do something similar to option (B). It all depends on your detailed requirements.

The right way to implement associations in DDD?

We are trying to adopt Domain-Driven Design in our project for the first time. The problem I have is with associations between entities. How do you do them right?
Say, I've got entities Employee and Contract, a simple one-to-many association. How do I model it?
Option 1: Aggregate.
Problem: The problem here is that, if I understand it correctly, all entities in an aggregate must be loaded when an aggregate object is created. I can't lazy-load entities when they are needed because it would require referencing a repository from an entity, which apparently is bad. But fetching all of an employee's contracts from the database every time would be a big performance issue.
Option 2: Fetching an employee's contracts by using a repository (e.g. ContractRepository.GetContractsForEmployee()) and adding EmployeeId property to Contract class.
Problem: it makes hard to put any business logic into entities. I would like to have a method, say, Employee.Dismiss(), but it would also need to update the employee's contract. This means I would need to put this logic in a service. The problem is, I can't think of much logic operating only on an Employee and thus the model would become somewhat anemic, with most logic inside services.
How do you deal with these issues in DDD?
This is just my take on it... without knowing your domain.
First, here is a good resource to read (part about Aggregates and Roots).
In DDD terminology, Employee and Contract are both entities (because they both have an identity).
"Aggregates draw a boundary around one or more Entities. and also: Each Aggregate has a Root Entity, which is the only member of the Aggregate that any object outside the Aggregate is allowed to hold a reference to."
The question is: do Employee and Contract form an aggregate, with Employee being the root entity? Obviously not, because other domain entities could also have a reference to a contract, and the contract id's are globally unique, not only within a Customer.
So, taking into account these rules, Employee and Contract are both aggregate roots.
Then: "Only aggregate roots can be obtained directly with queries; so this means that we should have a repository per aggregate root."
So in this case, we have an EmployeeRepository and a ContractRepository.
Taking all of this into account, I would not add a relation between employees and contracts in the domain model; but treat them separately. After all, if you need an Employee, you don't necessarily need his contracts too, they are both different aspects.
Option 2 is what I would choose: use the ContractRepository to get the contracts you are interested in. And if needed you could add a domain service that is responsible for aggregating employees and contracts if needed.
If you also define a Company entity, then dismissing an employee could be the job of that entity.
We recently got into the DDD approach as well. If I were to do it, I would have the following (attributes are simplified for brevity):
public class Employee() {
String name;
Set<ContractNumber> contracts;
public void addContract(ContractNumber contractNumber) {
this.contracts.add(contractNumber);
}
}
public class Contract() {
ContractNumber contractNumber;
Date effectiveDate;
}
public class ContractNumber() {
String contractNumber;
}
ContractNumber is a Value Object that is referred to from within Employee. In this example, Employee is within a BoundedContext that deals with Employees and their respective contracts. There may be other representations of Employee in other bounded contexts.
As discussed in other answers, there will be repositories for both Employee and Contract.
You need to find your true invariants.
Here you could have an invariant such as: you cannot dismiss an Employee that has already been dismissed.
If this is the only real invariant, then you could make one Employee aggregate, which would only have the IDs of the associated contracts.
Contract would be another aggregate (if needed).
If the dismiss() method succeeds, you could load the needed contracts and make the necessary changes.

What is the best way to create derived properties

I have a datamodel with to-many to-many relations. Using the example of employee database let say the entity division is related to department which in turn is related to employee. The employee has an attribute salary. How best to have a attribute at the level of division which is derived from the salary attribute. For example average salary or maximum salary.
I would need those attributes to sort the list of departments.
Have a look at this question in the Core Data FAQ. If you can't do it with KVC set/array operators, then you try to do the keyPathsForValuesAffectingValueForKey : trick. If that isn't viable, you have to use KVO to observe changes in the key path the value is derived from.
Have a look at the KVC Set and Array Operators. Using one of these (#avg in your example) wrapped in a custom read only property should fit the bill.