We all write code with some patterns even when we dont realise it. I am trying to really understand some of the S.O.L.I.D principles and how you apply these principles in the real world.
I am struggling with "D".
I sometimes confuse Dependency Inversion with Dependency Injection. Does it mean that as long as you keep things depending on abstraction (IE:interfaces) you are done.
Does anybody have even a small C# example that explains it?
Thanks.
Have a look at Mark Seeman's blog or, even better, buy his book. It covers so much more than just DI. I appreciate you probably just want a simple sample to get going with. However, it's a subject that many who claim to understand don't and therefore worth learning well.
That said, here's a very simple example. The terminology, as I understand it, is
Inversion of Control and Dependency Injection. Inversion of Control refers to the fact that you give control of a class's dependencies to some other class, opposed to the class controlling the dependency itself, usually via the new keyword. This control is exerted via Dependency Injection where a class is given, or injected, with its dependencies. This can be done via an IoC framework or in code (known as Pure DI). Injection can be performed in the class's constructor, via a property or as a method's parameter. Dependencies can be any type, they don't have to be abstract.
Here's a class that lists Tour de France winners who haven't doped:
class CleanRiders
{
List<Rider> GetCleanRiders()
{
var riderRepository = new MsSqlRiderRepository();
return riderRepository.GetRiders.Where(x => x.Doping == false);
}
}
This class is dependent on the MsSqlRiderRepository. The class takes control of the creation of the instance. The problem is that this dependency is inflexible. It's hard to change it to a OracleRiderRepository or a TestRiderRepository.
IoC and DI solve this for us:
class CleanRiders
{
private IRiderRepository _repository;
public CleanRiders(IRiderRepository repository)
{
_repository = repository;
}
List<Rider> GetCleanRiders()
{
return _repository.GetRiders.Where(x => x.Doping == false);
}
}
Now the class is only depending on an Interface. Control of the dependency has been given up to the class's creator and must be injected via its constructor:
void Main()
{
var c = new CleanRiders(new MsSqlRepository());
var riders = c.GetRiders();
}
Arguably, a more flexible, testable and SOLID approach.
S: Single Responsibility Principle
The following code has a problem. “Automobile” class contains two different responsibilities: First is to take care of the car model, adding accessories, etc. and then there is the second responsibility: To sell/lease the car. This breaks SRP. These two responsibilities are separate.
public Interface ICarModels {
}
public class Automobile : ICarModels {
string Color { get; set; }
string Model { get; set; }
string Year { get; set; }
public void AddAccessory(string accessory)
{
// Code to Add Accessory
}
public void SellCar()
{
// Add code to sell car
}
public void LeaseCar()
{
// Add code to lease car
}
}
To fix this issue, we need to break up the Automobile class and use separate interfaces:
public Interface ICarModels {
}
public class Automobile : ICarModels {
string Color { get; set; }
string Model { get; set; }
string Year { get; set; }
public void AddAccessory(string accessory)
{
// Code to Add Accessory
}
}
public Interface ICarSales {
}
public class CarSales : ICarSales {
public void SellCar()
{
// Add code to sell car
}
public void LeaseCar()
{
// Add code to lease car
}
}
While designing your interfaces and classes think about responsibilities. What will modifications to class involve? Break classes up into their simplest forms...but not any simpler (as Einstein would say).
O: Open/Closed Principle
When requirements change and more types are added for processing, classes should be extensible enough so that they don't require modifications. New classes can be created and used for processing. In other words classes should be extensible. I call this the "If-Type" principle. If you have lots of if (type == ....) in your code, you need to break it up into separate class levels.
In this example we are trying to calculate the total price of car models in a dealership.
public class Mercedes {
public double Cost { get; set; }
}
public class CostEstimation {
public double Cost(Mercedes[] cars) {
double cost = 0;
foreach (var car in cars) {
cost += car.Cost; } return cost; }
}
But a dealership does not only carry Mercedes! this is where the class is not extensible anymore! What if we want to add up other car model costs as well?!
public class CostEstimation {
public double Cost(object[] cars)
{
double cost = 0;
foreach (var car in cars)
{
if (car is Mercedes)
{
Mercedes mercedes = (Mercedes) car;
cost += mercedes.cost;
}
else if (car is Volkswagen)
{
Volkswagen volks = (Volkswagen)car;
cost += volks.cost;
}
}
return cost;
}
}
It's now broken! for every car model in the dealership lot we must Modify the class and add another if statement!
So let's fix it:
public abstract class Car
{
public abstract double Cost();
}
public class Mercedes : Car
{
public double Cost { get; set; }
public override double Cost()
{
return Cost * 1.2;
}
}
public class BMW : Car
{
public double Cost { get; set; }
public override double Cost()
{
return Cost * 1.4;
}
}
public class Volkswagen : Car
{
public double Cost { get; set; }
public override double Cost()
{
return Cost * 1.8;
}
}
public class CostEstimation {
public double Cost(Car[] cars)
{
double cost = 0;
foreach (var car in cars)
{
cost += car.Cost();
}
return cost;
}
}
Here the problem is solved!
L: Liskov Substitution Principle
The L in SOLID refers to Liskov principle. The inheritance concept of Object Oriented programming can be solidified where derived classes cannot modify behavior of base classes in any manner. I will come back to a real world example of LISKOV Principle. But for now this is the principle itself:
T -> Base
where as T [the derived class] should not be tampering with behavior of Base.
I: Interface Segragation Principle
Interfaces in c# lay out methods that will need to be implemented by classes that implement the interface. For example:
Interface IAutomobile {
public void SellCar();
public void BuyCar();
public void LeaseCar();
public void DriveCar();
public void StopCar();
}
Within this interface there are two groups of activities going on. One group belongs to a salesman and another belongs to a driver:
public class Salesman : IAutomobile {
// Group 1: Sales activities that belong to a salesman
public void SellCar() { /* Code to Sell car */ }
public void BuyCar(); { /* Code to Buy car */ }
public void LeaseCar(); { /* Code to lease car */ }
// Group 2: Driving activities that belong to a driver
public void DriveCar() { /* no action needed for a salesman */ }
public void StopCar(); { /* no action needed for a salesman */ }
}
In the above class we are forced to implement DriveCar and StopCar methods. Things that don't make sense for a salesman and do not belong there.
public class Driver : IAutomobile {
// Group 1: Sales activities that belong to a salesman
public void SellCar() { /* no action needed for a driver */ }
public void BuyCar(); { /* no action needed for a driver */ }
public void LeaseCar(); { /* no action needed for a driver */ }
// Group 2: Driving activities that belong to a driver
public void DriveCar() { /* actions to drive car */ }
public void StopCar(); { /* actions to stop car */ }
}
The same way we are now forced to implement SellCar, BuyCar and LeaseCar. Activities that clearly do not belong in Driver class.
To fix this issue we need to break up the interface into two pieces:
Interface ISales {
public void SellCar();
public void BuyCar();
public void LeaseCar();
}
Interface IDrive {
public void DriveCar();
public void StopCar();
}
public class Salesman : ISales {
public void SellCar() { /* Code to Sell car */ }
public void BuyCar(); { /* Code to Buy car */ }
public void LeaseCar(); { /* Code to lease car */ }
}
public class Driver : IDrive {
public void DriveCar() { /* actions to drive car */ }
public void StopCar(); { /* actions to stop car */ }
}
Segregation of Interfaces!
D : Dependency Inversion Principle
The question is: Who depends on who?
Let's say we have a traditional multi-layer application:
Controller Layer -> Business Layer -> Data Layer.
Assume from the Controller we want to tell the Business to save an Employee into the database. The Business Layer asks the Data Layer to perform this.
So we set out to create our Controller (MVC example):
public class HomeController : Controller {
public void SaveEmployee()
{
Employee empl = new Employee();
empl.FirstName = "John";
empl.LastName = "Doe";
empl.EmployeeId = 247854;
Business myBus = new Business();
myBus.SaveEmployee(empl);
}
}
public class Employee {
string FirstName { get; set; }
string LastName { get; set; }
int EmployeeId { get; set; }
}
Then in our Business Layer we have:
public class Business {
public void SaveEmployee(Employee empl)
{
Data myData = new Data();
myData.SaveEmployee(empl);
}
}
and in our Data Layer we create the connection and save the employee into the database. This is our traditional 3-Layer architecture.
Let's now make an improvement to our Controller. Instead of having SaveEmployee method right inside our controller, we can create a class that takes care of all Employee actions:
public class PersistPeople {
Employee empl;
// Constructor
PersistPeople(Employee employee) {
empl = employee;
}
public void SaveEmployee() {
Business myBus = new Business();
myBus.SaveEmployee();
}
public Employee RetrieveEmployee() {
}
public void RemoveEmployee() {
}
}
// Now our HomeController is a bit more organized.
public class HomeController : Controller {
Employee empl = new Employee();
empl.FirstName = "John";
empl.LastName = "Doe";
empl.EmployeeId = 247854;
PersistPeople persist = new Persist(empl);
persist.SaveEmployee();
}
}
Now let's concentrate on the PersistPeople class. It is hard-coded with and tightly coupled with the Employee class. It takes in an Emloyee in the contstructor and instantiates a Business class to save it. What if we want to save an "Admin" instead of "Employee"? Right now our Persist class is totally "Dependent" on the Employee class.
Let's use "Dependency Inversion" to solve this problem. But before doing that we need to create an interface that both Employee and Admin classes derive from:
Interface IPerson {
string FirstName { get; set; }
string LastName { get; set; }
int EmployeeId { get; set; }
}
public class Employee : IPerson {
int EmployeeId;
}
public class Admin : IPerson {
int AdminId;
}
public class PersistPeople {
IPerson person;
// Constructor
PersistPeople(IPerson person) {
this.person = person;
}
public void SavePerson() {
person.Save();
}
}
// Now our HomeController is using dependency inversion:
public class HomeController : Controller {
// If we want to save an employee we can use Persist class:
Employee empl = new Employee();
empl.FirstName = "John";
empl.LastName = "Doe";
empl.EmployeeId = 247854;
PersistPeople persist = new Persist(empl);
persist.SavePerson();
// Or if we want to save an admin we can use Persist class:
Admin admin = new Admin();
admin.FirstName = "David";
admin.LastName = "Borax";
admin.EmployeeId = 999888;
PersistPeople persist = new Persist(admin);
persist.SavePerson();
}
}
So in summary our Persist class is not dependent and hard-coded to Employee class. It can take any number of types like Employee, Admin, etc. The control to save whatever is passed in now lies with the Persist class and not the HomeController. The Persist class now knows how to save whatever is passed in (Employee, Admin, etc.). Control is now inverted and given to Persist class. You can also refer to this blog for some great examples of SOLID principles:
Reference: https://darkwareblog.wordpress.com/2017/10/17/
I hope this helps!
I was trying to explain this to my co-worker the other day and in the process I actually even understood the concept myself. Especially when I came up with the real-life example of dependency inversion in real life.
The story
Imagine if a car driver was dependent on a car: can only drive 1 car - THE car! This would be pretty bad:
In this case the direction of the dependency is: Driver => Car (the Driver object depends on the Car object).
Thankfully in real life each car has the interface: "steering wheel, pedals and gear shifter". A driver no longer depends on THE car, so a driver can drive ANY car:
Now TheDriver depends on the ICar interface, TheCar also depends on ICar interface - dependency is INVERTED:
I am no expert like others but will give a shot at explaining DIP with concept. At the heart of DIP is program to an interface i.e. your high level classes will rely on abstraction and your low level classes rely on the abstraction as well. for example
Lets say you define an abstraction called PhoneVendor i.e it can be samsung, apple, nokia etc.
Sorry about the code i haven't written Java for a while i.e it might have syntax error, but nonetheless its about the concept.
public abstract class PhoneVendor {
/**
* Abstract method that returns a list of phone types that each vendor creates.
*/
public abstract Vector getPhones(){ }
}
public class Samsung extends PhoneVendor{
public Vector getPhones(){ // return a list of phones it manufactures... }
}
public class PhoneFinder{
private PhoneVendor vendor;
public PhoneFinder(PhoneVendor vendor){ this.vendor = vendor;}
/**
*for example just return a concatnated string of phones
*/
public string getPhoneTypes(){
Vector ListOfPhones = PhoneVendor.getPhones();
return ListOfPhones;
}
}
As you can see PhoneFinder class depends on the abstraction not the implementation of the PhoneVendor. And your fundamental classes that implements the Abstraction are decoupled from the high level classes that use it. This makes the design really flexible where adding a new Low level classes wont break any previously written code since PhoneFinder is dependent on the abstraction not the implementation.
Related
I am thinking about the best practice in OOP for the following problem:
We have a program that is working with an external API.
The API has an object of type Element which is basically a geometric element.
Our application is a validation application that runs on a geometric model
The application takes a collection of those elements and performs some geometric tests on them.
We wrap this API element with our own class called "ValidationElement" and save some additional information to this wrapper element that can not be obtained directly from the API Element but is required by our application.
So far so good, but now the application should expand and support other types of models (basically we can say that the app is running in a different environment).
Specifically for this environment (and it does not apply to the previous cases), we want to save an additional parameter that obtaining it results in low performance.
What is the best practice option to implement it?
On one hand, I would like to avoid adding extra parameters that are not relevant to a specific(the first) part of the program.
And on the second hand, I am not sure that I want to use inheritance and split this object just for this small additional property.
public class ValidationElement
{
public Element Element { get; set; }
public XYZ Location {get; set;}//The extra property
}
The first and easy option is that the same class will have the additional property and calculation method:
public class ValidationElement
{
public Element Element { get; set; }
public XYZ Location {get; set;}//The extra property
public string AdditionalProperty { get; set; }
public void HardProcessingCalcOfAdditionalProperty()
{
//hard processing
AdditionalProperty = result
}
}
The second option that I mentioned is the inheritance
public class SecondTypeValidationElement : ValidationElement
{
public string AdditionalProperty { get; set; }
public void HardProcessingCalcOfAdditionalProperty()
{
//hard processing
AdditionalProperty = result
}
}
What do you think is the best practice for this? Is there any other way or design pattern that should help me achieve the goal?
I would like to avoid adding extra parameters that are not relevant to a specific(the first) part of the program.
It looks like it is a sign that an inheritance shoulbe be avoided here. As there is a strong possibility that this behaviour is not applicable for other classes.
And this is the second reason to avoid of creation some abstraction:
Element which is basically a geometric element
Because:
all derived elements will have these additional properties.
there are many articles which show how Liskov substitution principle can be violated in geometry figures
So let's prefer composition over inheritance.
So, in my view, it would be really good if we move all heavy, tightly coupled logic of calculating of additional property to separate class:
public class ValidationElement
{
public string Element { get; set; }
public SomeExtra AdditionalProperty { get; set; }
}
public class SomeExtra
{
public string Location { get; set; }//The extra property
public string AdditionalProperty { get; set; }
public void HardProcessingCalcOfAdditionalProperty()
{
//hard processing
AdditionalProperty = string.Empty;
}
}
Why have we created separate class SomeExtra and put logic here:
if we want to edit logic HardProcessingCalcOfAdditionalProperty, then we will edit just one class SomeExtra. By doing this we are satisfying Single Responsibility Principle of SOLID principles.
we can easily create some base abstract class for SomeExtra and then at runtime we can decide what concrete implementation should be injected. By doing this we are satisfying Open Closed Principle of SOLID principles.
UPDATE:
I really like this answer about whether inheritance or composition should be chosen:
My acid test for the above is:
Does TypeB want to expose the complete interface (all public methods no less) of TypeA such that TypeB can be used where TypeA is
expected? Indicates Inheritance.
e.g. A Cessna biplane will expose the complete interface of an airplane, if not more. So that makes it fit to derive from Airplane.
Does TypeB want only some/part of the behavior exposed by TypeA? Indicates need for Composition.
e.g. A Bird may need only the fly behavior of an Airplane. In this case, it makes sense to extract it out as an interface / class /
both and make it a member of both classes.
Update: Just came back to my answer and it seems now that it is incomplete without a specific mention of Barbara Liskov's Liskov
Substitution Principle as a test for 'Should I be inheriting from
this type?'
OOP and SOLID best practice is to use abstractions (interfaces or abstract classes), wich is closer to your second approach.
Dependency Inversion Principle:
The Dependency Inversion principle
states that our classes should depend upon interfaces or abstract
classes instead of concrete classes and functions.
Your first approach to edit the ValidationElement class is generally a bad idea, given that there are several environments for the project to be run onto.
In addition, maintaining and developing the project on this approach is not scalable and will be a headache in the long run.
Open-Closed Principle: The Open-Closed Principle requires that classes should be open for extension and closed to modification.
I suggest below designing:
public interface IValidationElement
{
Element Element { get; set; }
XYZ Location {get; set;}//The extra property
// declare other base properties and methods
}
public class ValidationElement: IValidationElement
{
public Element Element { get; set; }
public XYZ Location {get; set;}//The extra property
// define other base properties and methods
}
public interface ISecondTypeValidationElement: IValidationElement
{
string AdditionalProperty { get; set; }
void HardProcessingCalcOfAdditionalProperty();
}
public class SecondTypeValidationElement: ISecondTypeValidationElement
{
public string AdditionalProperty { get; set; }
public void HardProcessingCalcOfAdditionalProperty()
{
//hard processing
AdditionalProperty = result
}
}
public interface IThirdEnvironmentValidationElement: IValidationElement
{
string ThirdProperty { get; set; }
void RequiredProcessing();
}
public class ThirdEnvironmentValidationElement: IThirdEnvironmentValidationElement
{
public string ThirdProperty { get; set; }
public void RequiredProcessing()
{
//related operations
}
}
I am not going to repeat Open-close, DI, or other principals. It is already discussed. I would look at something like this, or even alternatively use Extensions to setup the value.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// old updated
public class Element
{
public Element(string msg) { Message = msg; }
public string Message;
}
public class XYZ { }
public class ABC { }
// new
public interface IDoesSomething
{
void SetResult();
}
// create 2 different wrappers
public class ValidationElementWrapper : IDoesSomething
{
public ValidationElementWrapper(Element el)
{
Element = el;
}
public Element Element { get; private set; }
public XYZ Location {get; set;}
public void SetResult()
{
Console.WriteLine("This is " + Element.Message);
// Do nothing
}
}
public class ValidationElementWrapper2 : IDoesSomething
{
public ValidationElementWrapper2(Element el)
{
Element = el;
}
public Element Element { get; private set; }
public XYZ Location {get; set;}
public string AdditionalProperty { get; set; }
public void SetResult()
{
AdditionalProperty = "Set additional property on wrapper 2";
Console.WriteLine("This is " + Element.Message + " and it has additional property - " + AdditionalProperty);
}
}
// run your program
public class Program
{
public static void Main()
{
var list = new List<IDoesSomething>();
list.Add(new ValidationElementWrapper(new Element("Element 1")));
list.Add(new ValidationElementWrapper2(new Element("Element 2")));
list.ForEach(item => item.SetResult());
}
}
Output
This is Element 1
This is Element 2 and it has additional property - Set additional property on wrapper 2
Alternatively, you can start with more basic class and then keep extending it
public class ValidationElementWrapper : IDoesSomething
{
public ValidationElementWrapper(Element el)
{
Element = el;
}
public Element Element { get; private set; }
public XYZ Location {get; set;}
public virtual void SetResult() // <--- virtual
{
// Do nothing
Console.WriteLine("This is " + Element.Message);
}
}
public class ValidationElementWrapper2 : ValidationElementWrapper // <-- inheritnce
{
public ValidationElementWrapper2(Element el) : base(el)
{
}
public XYZ Location {get; set;}
public string AdditionalProperty { get; set; }
public override void SetResult() // <--- override
{
AdditionalProperty = "Set additional property on wrapper 2";
Console.WriteLine("This is " + Element.Message + " and it has additional property - " + AdditionalProperty);
}
}
Result will be the same
This question already has answers here:
Using Interface variables
(12 answers)
Closed 5 years ago.
I have fair understanding of interface/abstract class/class however just trying to understand something else. Look at below code:
namespace AbstractClassExample
{
class Program
{
static void Main(string[] args)
{
BaseEmployee fullTimeEmployee = new FullTimeEmployee();
BaseEmployee contractEmployee = new ContractEmployee();
}
}
public abstract class BaseEmployee
{
public string EmployeeID { get; set; }
public string EmployeeName { get; set; }
public string EmployeeAddress { get; set; }
public abstract double CalculateSalary(int hoursWorked);
}
public class FullTimeEmployee : BaseEmployee
{
public override double CalculateSalary(int hoursWorked)
{
//do something
}
}
public class ContractEmployee : BaseEmployee
{
public override double CalculateSalary(int hoursWorked)
{
//do something
}
}
}
however I fail to get below lines (1st approach):
BaseEmployee fullTimeEmployee = new FullTimeEmployee();
BaseEmployee contractEmployee = new ContractEmployee();
Why not written this way instead (2nd approach):
FullTimeEmployee fullTimeEmployee = new FullTimeEmployee();
it is completely okay to use 2nd approach it will work coz of relation. How would any developer in the work know if above abstract class is in DLL. Probably, will use 1st approach when you've code with you or sort of documentation. Isn't it?
Similar example would also be valid for interface declaration. like:
interface IPointy {
void MyMethod();
}
class Pencil : IPointy {
void MyMethod() {
}
void MyOtherMethod() {
}
}
IPointy itPt = new Pencil();
Isn't 1st approach making it complex? What's good practice? Any good practice vs bad practice with 1st & 2nd?
Using the first approach enables Polymorphism.
Let's say you have a company class:
class Company {
}
Of course, companies have full-time and contract employees. Let's add them as properties:
public FullTimeEmployee[] EmployeesFullTime { get; set; }
public ContractEmployees[] EmployeesContract { get; set; }
This seems all good.
But, what if your company can now have yet another kind of employee that has a different way of calculating his salary? You have to add another property:
public FullTimeEmployee[] EmployeesFullTime { get; set; }
public ContractEmployee[] EmployeesContract { get; set; }
public AnotherKindOfEmployee[] EmployeesOther { get; set; }
That's no good, is it? Every time you add a new kind of employee, you have to add another property!
That's why you use BaseEmployee, it does not care about what kind of employee it holds, and it can still calculate salary!
public BaseEmployee[] AllEmployees { get; set; }
One of the reasons that you'd assign a FullTimeEmployee to a BaseEmployee is that you can put them together into a collection of FullTimeEmployees' andContractEmployees`:
List<BaseEmployee> allEmployees = new List<BaseEmployee>()
{
new FullTimeEmployee() {...},
new FullTimeEmployee() {...},
new ContractEmployee() {...},
new FullTimeEmployee() {...},
}
This has the disadvantage that you can't use (efficiently) functionality of a FullTimeEmployee that ContractEmployees don't have, but if you don't need this functionality while processing allEmployees, this method is preferable above creating two collections of employees. For instance, you could write one function that would work for both FullTimeEmployees and ContractEmployees:
private void PaySalary(List<BaseEmployee> employees)
{
foreach (var employee in employees)
{
var salary = employee.CalculateSalary()
Pay(salary, ...);
}
}
One of the guidelines when creating an object oriented design is that you should design for change, meaning that your design should be such that you could easily add types to your design, or change internals of your classes.
Suppose you'll need a new type of employees, HiredEmployees. Because you derived them from BaseEmployee, you'll know you can calculate their salary. You don't have to change function PaySalary.
This would also have worked if you'd given your FullTimeEmployee and your ContractEmployee an interface:
interface ISalaryReceiver
{
double CalculateSalary(int hoursWorked);
}
class BaseEmployee
{
public string EmployeeID { get; set; }
...
}
class FullTimeEmployee : BaseEmployee, ISalaryReceiver
{
public override double CalculateSalary(int hoursWorked)
{
...
}
}
class ContractEmployee : BaseEmployee, ISalaryReceiver
{
public double CalculateSalary(int hoursWorked)
{
...
}
}
void PaySalary(List<ISalaryReceiver> employees)
{
...
}
This method would work. It is even ready for change: you can invent any employee as long as it implements ISalaryReceiver.
However!
Suppose your BaseEmploye has a function where it needs to CalculateSalary:
class BaseEmployee
{
...
public void PaySalary()
{
double salary = ... // how to calculate the salary?
}
}
You can't let BaseEmployee implement ISalaryReceiver, because a BaseEmployee doesn't know how to calculate the salary.
When using the abstract method, you can tell BaseEmployee, that every object of BaseEmployee knows how to CalculateSalary:
abstract class BaseEmployee
{
abstract double CalculateSalary(...);
public void PaySalary()
{
double salary = this.CalculateSalary(...);
...
}
}
So if your base class needs functions that are different per derived class, and there is no proper default functionality, then your base class needs an abstract function. It is guaranteed that every derived class has implemented this function, and thus the base class can call it.
Because in such cases it is not meaningful to create objects of the base class (after all, the base class doesn't know how to CalculateSalary), the base class has to be declared abstract with the result that you can't create objects of base class. Only object of derived classes that implement CalculateSalary can be created.
One of the benefits of abstract classes is - you can use abstract type for argument type in the method.
Suppose you have a Report class with method Generate which during report generation need to calculate employee salary
public class Report
{
public SalaryReport Generate(BaseEmployee employee)
{
// ...
var salary = employee.CalculateSalary();
// ...
}
}
You don't want use if..else statement in every method where you need calculate salary.
So in Report class doesn't care how CalculateSalary implemented, it only cares that Employee class have this method.
Currently, am working on architecture of application, I have many entities in my project i.e student teacher university, I was wondering about is it a good practice that all entity must implement interface. This will help me in dependency injection? What is the best practice from architecture point of view.
public interface IMyEntity
{
//an empty interface
}
public class Student:IMyEntity
{
}
public class Teacher:IMyEntity
{
}
//hi I can deal with every object which implement IMyEntity
void Display(IMyEntity entity) //this function can be in some class
{
// if IMyEntity is teacher behave like a teacher
// if IMyEntity is student behave like sutdent
}
I know interface is a contract, but from architecture point of view it is best practice? I know my IMyEntity interface is empty.
Not necessarily. If in this case Student and Teacher have some common functionality then a shared interface would be one approach to take.
public void Display(IUniPerson person)
{
var name = person.Name; // Everyone, student or teacher, has a name
...
}
However, the example you give seems to suggest that this is not the case, and the Display method will attempt to treat the passed in instance of IMyEntity differently depending on it's type. In that case, you may be better with 2 Display methods with different parameters.
public void Display(ITeacher teacher) { // teacher processing }
public void Display(IStudent student) { // student processing }
tl:dr version: implement an interface across multiple classes if it makes sense for those classes to implement related methods and functions, rather than just as a blanket rule.
I think that decoupling 2 or more classes is a good taste in terms of developing and it really helps maintaining the code in a long run.
Consider the follow scenario:
static void Main(string[] args)
{
var objA = new A();
var objB = new B(objA);
}
public class A {}
public class B
{
public B(A obj)
{
//Logic Here
}
}
The problem with this code it's that it's strongly coupled, class B needs class A to be instanced and do it's business.
This is not a problem if you are sure that B is never going to have some drammatic change.
Now if we want to decouple it we can make a first improvement implementing an interface like
static void Main(string[] args)
{
var objA = new A();
var objB = new B(objA);
}
public interface IA()
{
//TODO
}
public class A : IA {}
public class B
{
public B(IA obj)
{
//Logic Here
}
}
It looks quite better what we still have a couplation problem in the Main, so at this point we will have to implement a Dependency Injection with a IOC like Ninject, and our code will be like to something like:
static void Main(string[] args)
{
var objB = new B();
}
public interface IA()
{
//TODO
}
public class A : IA {}
public class B
{
public B(IA obj)
{
//Logic Here
}
}
Yes, that looks good. We have completely removed the couplation problem and it will be quite easy if in the future we just need to take A, delete it and replace it wich something new more cool.
Obviously overkilling it's a bad practice and I belive DI must be used only after carefuly planning to avoid useless implementations.
For example if I have a class C which has some basic operations, and I am sure that it will never change or have some drammatic need to update i can avoid DI.
So do you have to implement interfaces on every model in your project?
Well I don't think each model in your project needs to implements an interface or DI, just think about it and see where it can be useful and where it's just overkilling.
Looking at how .NET solved this, you can see some ambiguity.
For instance for every object has a function where you can ask for a string representation of the object: ToString(), even though for a string representation might not be a meaningful thing for a lot of classes
On the other hand, although it would be a useful function for every object to make a clone of itself they decided not to let every class implement ICloneable.
Whether it is wise for you to have (almost every) objects of your application a common interface depends on what you will do with this interface and the advantage of all objects implementing such an interface versus the burden of being obliged to implement the interface.
For example, if the entities you are talking about are database records, then it is very likely that every class will have some kind of ID. You could consider giving every class an interface with one get property that returns the value of the ID of the record.
public interface IID
{
long ID {get;}
}
The advantage are multifold:
You encourage every designer of database classes to implement the same type of primary key (in this case a long), and the same property name
Advantage: it is easier to spot the ID of a record
Advantage: it is easier to change the type of the ID
Advantage: you know if you have a database record, you know some of the functions the record must have, without really knowing the type of the record.
Even if the designer needs a different type, or different name, he can still create a special function to implement the interface:
public class Person : IID
{
public int ID {get; set;}
IID:ID {get {return this.ID;} }
}
However, I suggest not to force interfaces to object for which it is not natural to have them. This has the advantage that you can't use these strange functions for object that have no real usage for them.
For example, most classes that represent some ordered numerical value have some notion of addition. Not only for integers and real numbers, but also for classes that represent a time span: 4 days and 23 hours + 1 day and 7 ours = 6 days and 6 hours. So for a time span addition is a useful interface
However, for a date, addition is not meaningful: 4th of july + 14 juillet = ?
So: Yes, implement interfaces for items that are natural to them. They force common naming and enable reuse. No, don't implement them for items that do not have a natural meaning for the functions.
Yes do it like this, it is the best practise. This gives you the advantage of polymorphism. You should do it in better way in current context is not good, because Student is not a Teacher. If you want to share common interface you should define it as: IUniversityMember. Here an example for your case which I think will make it clear.
public interface IUniversityMember
{
//... here common fields between `Teacher` and `Student`
string Name{ get; set;}
string Gender { get; set;}
}
//after that
public interface IStudent
{
int GetGPA();
int CreditsToPass {get; private set;}
}
public interface ITeacher
{
int WorkedHours {get; set;}
decimal PayPerHour {get; private set;}
}
public class BiologicalStudent: IUniversityMember, IStudent
{
public int CreditsToPast {get; private set;}
public BiologicalStudent ()
{
CreditsToPast = 5;
}
//stuff
public int GetGPA()
{
return 3;
}
}
public class MathStudent: IUniversityMember, IStudent
{
public int CreditsToPast {get; private set;}
public BiologicalStudent ()
{
CreditsToPast = 9;
}
public int GetGPA()
{
return 2;
}
}
public class BiologicalTeacher: IUniversityMember, ITeacher
{
public int WorkedHours { get; set;}
public decimal PayPerHour {get; private set;}
public MathTeacher()
{
PayPerHour = 8;
}
}
public class MathTeacher: IUniversityMember, ITeacher
{
public int WorkedHours { get; set;}
public decimal PayPerHour {get; private set;}
public MathTeacher()
{
PayPerHour = 10;
}
}
//Now if you have a university class
public class OxfordUniversity:IUniversity //can inherit interface too
{
public int MinGAPForSchollarship {get; private set;}
public OxfordUniversity()
{
MinGAPForSchollarship = 3;
}
public decimal PaySallary(ITeacher teacher)
{
return teacher.WorkedHours*teacher.PayPerHour;
}
public bool CheckForSchollarship(IStudent student)
{
int gpa = student.GetGPA();
//do some checks
if(gpa >= MinGAPForSchollarship)
return true;
return false;
}
}
Let's say I've such code
public class Holded
{
protected internal int holdedID = 0;
}
public class Inventory : Holded
{
public Inventory() { }
public void changeHoldedID()
{
this.holdedID = 100;
}
}
public class Equipment : Holded
{
public Equipment() { }
public void writeHoldedID()
{
Console.WriteLine("Holded ID is: {0}!", this.holdedID);
}
}
public class Cargo : Holded
{
public Cargo() { }
}
If I'd call changeHoldedID and then writeHoldedID, console will still output a string like "Holded ID is: 0!". Now what I want to achieve is to have same base class (Holded) in both of classes. So if I'd change holdedID from Inventory, Equipment's writeHoldedID function would output "Holded ID is: 100!". Thanks and regards!
#Edit: More detailed: I have a game. Each person is a character, that owns Equipment, Inventory and Cargo class. Each class contains about 20 slots for "items". Now the thing is, that if you try to move an item, for ex. from inventory, to equipment, and there's such index of item, then the item is "swapped" - goes holded, and now I may throw such holded item into Equipment, Inventory or Cargo. That's why I'm in need to share such class between Eq/Inv/Cargo.
With this inheritance structure, what you are asking is 99.9% impossible.
When you create an Inventory object, you are also creating a Holded object with its own holdedID member. When you create an Equipment object, you get a new Holded object as well, with no relation to the old one. Thus, changes to one objects member won't affect the other, and you want it this way.
*To be clear, you don't get a seperate Holded object when creating a derived class, but it can be helpful to think of it in the way I described it.
I don't know why you want to do what you are asking, but its a pretty good bet you need to rework your understanding of inheritance, objects, and polymorphsim.
Now, I said this was 99.9% impossible. You can mark the base class member static which shares it among all instances of Holded (and derived classes), making your code possible. However, there is almost no chance you actually want to do this. static should only be used when you understand object-oriented design and the consequences of using it.
Have you considered, instead of "is a" inheritance type relationship a "contains a" relationship?
You could do something along the following lines:
public interface IHolded
{
Bar Foo();
}
public class Holded: IHolded { ... }
And now you have two options in how you want to implent Equipment and Inventory:
Directly exposing holded throgh a readonly property:
public class Inventory
{
public Inventory(IHolded holded) { ... }
public IHolded Holded { get; }
}
Having them implement the IHolded interface and delegating
implementation to holded.
public Equipment
{
private readonly IHolded holded;
public Equipment(IHolded holded) { this.holded = holded; }
public Bar Foo() { return holded.Foo() };
}
This way you are injecting a Holded object when creating Equipment and Inventory instances ensuring a consistent state in both instances.
A Dictionary to store the person and their HoldedId might work
public class Holded
{
protected internal static Dictionary<string, int> _personHoldedIDs;
internal string _person;
public Holded(string person)
{
_person = person;
if (_personHoldedIDs == null)
_personHoldedIDs = new Dictionary<string, int>();
if (!_personHoldedIDs.ContainsKey(_person))
_personHoldedIDs.Add(_person, 0);
}
}
public class Inventory : Holded
{
public Inventory(string person) : base(person) { }
public void changeHoldedID()
{
_personHoldedIDs[_person] = 100;
}
}
public class Equipment : Holded
{
public Equipment(string person) : base(person) { }
public void writeHoldedID()
{
Console.WriteLine("Holded ID is: {0}!", _personHoldedIDs[_person]);
}
}
I'm trying to get my head around a polymorphism/inheritance situation in C#.
What I have right now is these classes:
Lease (the base class containing the general data)
PrivateLease (inheriting from the Lease class)
BusinessLease (inheriting from the Lease class)
What I want to achieve is this:
Lease lease = new PrivateLease();
This works at the moment, but I am not able to access the properties on the PrivateLease object when doing this. At least not without casting the Lease object to a PrivateLease object first.
I'd like the Lease object to be the general object of either a PrivateLease or BusinessLease object which holds all the data for one of the objects. Then when inserting/updating/deleting to the database I'm going to ask which type it is first to dertermine which tables to insert the data into.
I've got a strange feeling that the above is not the right approach to solve this problem. Does anyone have any hints on this? :-) I've searched on google and read in my programming books and everyone suggests this approach of having a base class and then inherit from it to the other classes.
Any help/hint is greatly appreciated!
Thanks in advance.
EDIT
Should've elaborated a bit on this from the beginning, I'm sorry for that!
The above mentioned classes are merely just holding data from the UI of my ASP.NET solution to perform CRUD operations against the database via a Data Access Layer. So bascially these classes only contains a bunch of properties to hold data. I.e:
public class Lease
{
public int Id { get; set; }
public bool IsActive { get; set; }
public string TypeOfRental { get; set; }
public string RentalPeriod { get; set; }
public DateTime TakeoverDate { get; set; }
}
public class PrivateLease : Lease
{
public string Floor { get; set; }
public string Side { get; set; }
public int FloorSize { get; set; }
public int NumberOfRooms { get; set; }
}
etc..
The PrivateLease and BusinessLease classes are different because of the different leaseing-variables that exists in the real world :-)
Basically I could just go with the two separate PrivateLease and BusinessLease objects, but since the model dictates that an Address object can hold one or more Leases, this is not an option.
To me it seems like I'm going to go through a major casting hell both on the ASP.NET frontend and on the DAL? :-/
Don't decide (choose a logic) on the layer of consumer, but let to decide by the classes themselves:
// or you ILease interface if a parent class will not contain any shared logic
abstract class Lease
{
public abstract void Do();
// example of shared logic
protected void Save(Lease l) { }
}
class PrivateLease : Lease
{
public override void Do() { // private logic here }
}
class BusinessLease : Lease
{
public override void Do() { // business logic here }
}
Usage:
Lease l = ...
l.Do(); // execute the logic
You may want to create a factory for objects creation:
static class LeaseFactory<T> where T : Lease, new() // constraint to require default constructor existence
{
public static Leas Create()
{
return new T();
}
}
You're right in the basic approach of having a base class.
What you need to do is to put any common properties in the base class. Then if you have different business rules, those can be implemented with virtual functions, being called polymorphically.
abstract class Lease
{
public int MonthlyCost {get;set;}
public string CustomerName {get;set;}
// Declare that all Leases have to have an IncreaseCost method.
public abstract void IncreaseCost();
}
class PrivateLease : Lease
{
// Private leases are incremented by an absolute number (10).
public override void IncreaseCost()
{
MonthlyCost += 10;
}
}
class BusinessLease : Lease
{
// Business leases are incremented by 10%.
public override void IncreaseCost()
{
MonthlyCost *= 1.10;
}
}
// Somewhere in your code...
Lease lease = new PrivateLease();
// This call is polymorphic. It will use the actual type of the lease object.
lease.IncreaseCost();
In the modern OOD you can use interfaces, for this situation.
Edit:
In my opinion, to avoid casting, you can have multiple interfaces for multiple purposes. then PrivateLease and BusinessLease can implement the appropriate ones.
interface IWrite
{
string Data { get; set; }
void Write();
}
interface IRead
{
string Data { get; set; }
void Read();
}
public class Lease
{
//..
}
public class PrivateLease : Lease, IWrite, IRead
{
// other implementations
public string Data { get; set; }
public void Read()
{
//..
}
public void Write()
{
//..
}
}
public class BusinessLease : Lease, IRead
{
// other implementations
public string Data { get; set; }
public void Read()
{
//..
}
}
In Lease class add virtual method called DBUpdate and override it in both the derived classes.
Let's say some Utility class has LeaseDBOperation Method looks like this :
public static void LeaseDBOperation (Lease anylease)
{
anyleaase.DBUpdate();
}
you can call this method as :
var pl = new PrivateLease();
..set all the properties of **pl**
//call this for db operations :
Utility.LeaseDBOperation(pl)
Here in LeaseDBOperation method , if based on the type send , DBUpdate method of required class will be called.
Lease l = (Lease)sth;
if (l is PrivateLease)
{
PrivateLease p = (PrivateLease)l;
//do private logic here
}
else if (l if BussinessLease)
{
BussinessLease b = (BunessinessLease)l;
//do bussiness logic here
}