violation of SOLID principles - oop

suppose we have a class structure where the code is divided in two parts lets us say computer science and business, now this also further divides in terms of country also, say Indian (cs or MBA) and US (cs or MBA).
now let us consider a scenario where i created classes like
1)Education class(parent class)
2) MBA class extends Education class
3) BS (cs) class extends Education class
now in terms of country also i made the classes
4) INDIA_BS class extends BS (cs) class
5)INDIA_MBA class extends MBA class
6) US_BS class extends BS (cs) class
7) US_MBA class extends MBA class
now let us say i write code where the country is set in the classes-method which are lowest in hierarchy (i.e country classes INDIA_BS,INDIA_MBA,US_BS,US_MBA)
but the logic is similar.I pass country name and it is set.
so my questions are
1) is it wise to put the common logic in parent classes(if i do that way) and calling that method from the child class which is lowest in hierarchy).
2) if this is wrong than what are the principles of OOPS that it violate
3) does it violate SOLID principle also if yes then how ?
4) is it decreasing coherence of the child class if i am putting the common code in parent class.
please be elaborate as possible.
thanks

Your class diagram:
i see x violations:
Favor Composition Over Inheritance
Program To An Interface, Not An Implementation
Software Entities Should Be Open For Extension, Yet Closed For Modification
etc
So, i would suggest you use Abstract Factory pattern.
Code:
class Test
{
static void Main(string[] args)
{
IEducationFactory india = new IndianEducation();
IEducationFactory newYork = new USEducation();
IDiplom d1 = india.Create_BSC();
IDiplom d2 = newYork.Create_MBA();
}
}
public interface IDiplom
{
}
public interface IEducationFactory
{
IDiplom Create_MBA();
IDiplom Create_BSC();
}
public class IndianEducation : IEducationFactory
{
public IDiplom Create_MBA()
{
throw new NotImplementedException();
}
public IDiplom Create_BSC()
{
throw new NotImplementedException();
}
}
public class USEducation : IEducationFactory
{
public IDiplom Create_MBA()
{
throw new NotImplementedException();
}
public IDiplom Create_BSC()
{
throw new NotImplementedException();
}
}
And, your class diagram looks like:

Related

Allow conditional class inheritance

This is a question asked to me in an interview.
I have one class say EmployeeClass with two method. EmployeeDetails, SalaryDetails.
Now I have two More Class Employee and Hr. My need is when I create employee object only EmployeeDetails() method should be accessible and when when i create HR class both EmployeeDetails() and SalaryDetails() should be accessiable. I need to define a prototpe using all solid principle.
Class EmployeeClass
{
EmployeeDetails();
SalaryDetails();
}
and:
Class Employee
{
}
Class Hr
{
}
and:
void Main()
{
var employee = new Employee();
employee.EmployeeDetails(); // Only Employee Details is visible
var hr= new HR();
hr.EmployeeDetails();
hr.SalaryDetails(); // Both EmployeeDetails() and
// SalaryDetails() should be visible.
}
This isn't really how inheritance is designed to work. If some derived classes will inherit only some methods from base class, then it would be violation of Liskov substitution principle. What is an example of the Liskov Substitution Principle?
But you can inherit interface. Let me show an example.
These are interfaces. Pay attention to IHr interface. IHr inherits IEmployee interface:
public interface IEmployee
{
string GetEmployeeDetails();
}
public interface IHr: IEmployee
{
string SalaryDetails();
}
And its concrete implementations:
public class Employee : IEmployee
{
public string GetEmployeeDetails()
{
return "Employee. EmployeeDetails";
}
}
public class Hr : IHr
{
public string GetEmployeeDetails()
{
return "Hr. EmployeeDetails";
}
public string SalaryDetails()
{
return "Hr. SalaryDetails";
}
}
And you can use them like this:
IEmployee employee = new Employee();
employee.GetEmployeeDetails();
IHr hr = new Hr();
hr.SalaryDetails();
hr.GetEmployeeDetails();

Paradigm "program to interfaces, not implementations" vs. builder pattern

I like the builder pattern (example https://stackoverflow.com/a/1953567) for various reasons, e. g. the fact that I can work with immutable objects and that I can control the object creation in the way that no invalid objects can be created.
However, I try to follow the paradigm "program to interfaces, not implementations" (example https://stackoverflow.com/a/2697810).
I figured, these two guidelines do not play well together.
If I have an interface Person and a class PersonImpl and a builder PersonImplBuilder that builds a PersonImpl. I now can assure that every instance of PersonImpl is valid and immutable. But every return value and particularly every method parameter in my API uses the interface. So I can not depend on a valid object.
Am I missing something respectively is there another way of combining these two very useful guidelines?
EDIT
Some code to clarify.
In this example the builder is useless in terms of ensuring validity and/or imutability of the object in my API. It does only guarantee that any object of PersonImpl is valid (and by the way that only works because PersonImpl ist declared as final). But I can not control if a client is actually using my safely constructed PersonImpl object or any other implementation of the Person interface.
public interface Person {
LocalDate getBirthday();
}
public final class PersonImpl implements Person {
private final LocalDate birthday;
private PersonImpl(PersonImplBuilder builder) {
this.birthday = builder.birthday;
}
#Override
public LocalDate getBirthday() {
return birthday;
}
}
public class PersonImplBuilder {
private LocalDate birthday;
public LocalDate getBirthday() {
return birthday;
}
public void setBirthday(LocalDate birthday) {
this.birthday = birthday;
}
public PersonImpl build() {
if(birthday.isAfter(LocalDate.now().minusYears(21).minusDays(1))) {
throw new IllegalStateException("Person must be 21 years or above");
}
return new PersonImpl(this);
}
}
// this is my API
public interface PersonService {
void doSomeAdultStuff(Person person);
}
public class PersonServiceImpl implements PersonService {
//...
}
public void maliciousMethod() {
PersonService service = new PersonServiceImpl();
service.doSomeAdultStuff(new Person() {
#Override
public LocalDate getBirthday() {
return LocalDate.now();
}
});
}
You don't use the builder anywhere in your code. If you don't want to your code to use different implementations of the Person class but just your PersonImpl then don't use the interface but the concrete implementation. This way you will be sure that you have only objects build the way you want.
You should consider that a person can be less than 21 years old and still be a "valid" person (A child for example). You can have adult builder and child builder (different implementations) but you still would need to check if you got the right implementation. So maybe you should check in the service if the person has a correct age and not during building the object. Otherwise it should be called Adult and not a Person ;)
The combination of "program to interface" concept and Builder pattern should have no issue. The reason is in your following code:
service.doSomeAdultStuff(new Person() {
#Override
public LocalDate getBirthday() {
return LocalDate.now();
}
});
You wrote a new class that has no name and implements the Person interface (anonymous class). This class is different with PersonImpl class of your code. In your case just remove anonymous class implementation and use new PersonImpl(builder) instead.
service.doSomeAdultStuff(new PersonImpl(builder));

How to handle more than 100 classes through Polymorphism without violating Open Closed Principle

Suppose I have a class called A and there are two versions to it A1 and A2.
class A{};
class A1 : A{};
class A2 : A{};
and I have one more class which would use these.
class B
{
B(A obj)
{
if(obj.type(A1)){}//do this
else(obj.type(A2)){})//do this
}
}
Questions:
1) Suppose there are 100 or 1000 of classes derived from A,then how do I implement it in the constructor of B, by using "switch" or "if"> In both cases if I have to extend the class I will violate the "open closed principle".
2) if(obj.type(A1)) is this implementation the best way to implement for detecting which class object is there.
If you have a 100 classes derived from the same base class, you need to re-consider your design.
That said, sometimes you have a large number of classes doing similar things.
One option is to use an interface, have your different classes implement that interface, and the "do this" implemented in each subclass separately:
class B { B(A obj) {
if(obj.type(A1)){}//do this
else(obj.type(A2)){})//do this
} }
becomes
interface AInterface
{
public void doThis();
}
abstract class A implements AInterface
{
...
}
class A1 extends A
{
public void doThis()
{
...
}
}
class A2 extends A
{
public void doThis()
{
...
}
}
class B { B(AInterface obj) {
obj.doThis();
} }
Another, more advanced approach is to use the Visitor design pattern.

How Dynamic binding works in java

I am beginner to java and trying to understand Dynamic binding
when i come across this below example,
class Animal{}
class Dog extends Animal{
public static void main(String args[]){
Dog d1=new Dog();
}
}
Here d1 is an instance of Dog class, but it is also an instance of
Animal.
here what i dont understand is,How d1 is also become an instance of Animal class when you do inherit in java.
Can someone explain this concept.
Why they say "d1 is also an instance of Animal", what they really mean is that d1 can be used like an instance of Animal. You can use d1 to do everything an instance of Animal can do, including but not limited to:
Passing d1 to an Animal parameter
public static void method(Animal a) { ... }
...
method(d1); // compiles!
Assigning d1 to a variable of type Animal
Animal myAnimal = d1;
Calling methods that is in the Animal class
d1.move();
The reason why you can do all these is all because of that extends keyword.
Dynamic binding occurs during the run time.It is also known as Late binding as it occurs in the run time.The type of the object cannot be determined during the compile time.The parent class and the child class has the same method but the method is overridden.
Simple example to understand Dynamic binding
class Animal{
void eat(){
System.out.println("Animal is Eating");
}
}
class Dog extends Animal{
void eat(){
System.out.println("Dog is Eating");
}
}
class Test{
public static void main(String [] args){
Animal obj = new Animal();
obj.eat(); // displays Animal is Eating
Animal obj1 = new Dog(); // reference of the parent class
obj1.eat(); // displays Dog is Eating
}
}

design pattern query

i have a question regarding design patterns.
suppose i want to design pig killing factory
so the ways will be
1) catch pig
2)clean pig
3) kill pig
now since these pigs are supplied to me by a truck driver
now if want to design an application how should i proceed
what i have done is
public class killer{
private Pig pig ;
public void catchPig(){ //do something };
public void cleanPig(){ };
public void killPig(){};
}
now iam thing since i know that the steps will be called in catchPig--->cleanPig---->KillPig manner so i should have an abstract class containing these methods and an execute method calling all these 3 methods.
but i can not have instance of abstract class so i am confused how to implement this.
remenber i have to execute this process for all the pigs that comes in truck.
so my question is what design should i select and which design pattern is best to solve such problems .
I would suggest a different approach than what was suggested here before.
I would do something like this:
public abstract class Killer {
protected Pig pig;
protected abstract void catchPig();
protected abstract void cleanPig();
protected abstract void killPig();
public void executeKillPig {
catchPig();
cleanPig();
killPig();
}
}
Each kill will extend Killer class and will have to implement the abstract methods. The executeKillPig() is the same for every sub-class and will always be performed in the order you wanted catch->clean->kill. The abstract methods are protected because they're the inner implementation of the public executeKillPig.
This extends Avi's answer and addresses the comments.
The points of the code:
abstract base class to emphasize IS A relationships
Template pattern to ensure the steps are in the right order
Strategy Pattern - an abstract class is as much a interface (little "i") as much as a Interface (capital "I") is.
Extend the base and not use an interface.
No coupling of concrete classes. Coupling is not an issue of abstract vs interface but rather good design.
public abstract Animal {
public abstract bool Escape(){}
public abstract string SaySomething(){}
}
public Wabbit : Animal {
public override bool Escape() {//wabbit hopping frantically }
public override string SaySomething() { return #"What's Up Doc?"; }
}
public abstract class Killer {
protected Animal food;
protected abstract void Catch(){}
protected abstract void Kill(){}
protected abstract void Clean(){}
protected abstract string Lure(){}
// this method defines the process: the methods and the order of
// those calls. Exactly how to do each individual step is left up to sub classes.
// Even if you define a "PigKiller" interface we need this method
// ** in the base class ** to make sure all Killer's do it right.
// This method is the template (pattern) for subclasses.
protected void FeedTheFamily(Animal somethingTasty) {
food = somethingTasty;
Catch();
Kill();
Clean();
}
}
public class WabbitHunter : Killer {
protected override Catch() { //wabbit catching technique }
protected override Kill() { //wabbit killing technique }
protected override Clean() { //wabbit cleaning technique }
protected override Lure() { return "Come here you wascuhwy wabbit!"; }
}
// client code ********************
public class AHuntingWeWillGo {
Killer hunter;
Animal prey;
public AHuntingWeWillGo (Killer aHunter, Animal aAnimal) {
hunter = aHunter;
prey = aAnimal;
}
public void Hunt() {
if ( !prey.Escape() ) hunter.FeedTheFamily(prey)
}
}
public static void main () {
// look, ma! no coupling. Because we pass in our objects vice
// new them up inside the using classes
Killer ElmerFudd = new WabbitHunter();
Animal BugsBunny = new Wabbit();
AHuntingWeWillGo safari = new AHuntingWeWillGo( ElmerFudd, BugsBunny );
safari.Hunt();
}
The problem you are facing refer to part of OOP called polymorphism
Instead of abstract class i will be using a interface, the difference between interface an abstract class is that interface have only method descriptors, a abstract class can have also method with implementation.
public interface InterfaceOfPigKiller {
void catchPig();
void cleanPig();
void killPig();
}
In the abstract class we implement two of three available methods, because we assume that those operation are common for every future type that will inherit form our class.
public abstract class AbstractPigKiller implements InterfaceOfPigKiller{
private Ping pig;
public void catchPig() {
//the logic of catching pigs.
}
public void cleanPig() {
// the logic of pig cleaning.
}
}
Now we will create two new classes:
AnimalKiller - The person responsible for pig death.
AnimalSaver - The person responsible for pig release.
public class AnimalKiller extends AbstractPigKiller {
public void killPig() {
// The killing operation
}
}
public class AnimalSaver extends AbstractPigKiller {
public void killPing() {
// The operation that will make pig free
}
}
As we have our structure lets see how it will work.
First the method that will execute the sequence:
public void doTheRequiredOperation(InterfaceOfPigKiller killer) {
killer.catchPig();
killer.cleanPig();
killer.killPig();
}
As we see in the parameter we do not use class AnimalKiller or AnimalSever. Instead of that we have the interface. Thank to this operation we can operate on any class that implement used interface.
Example 1:
public void test() {
AnimalKiller aKiller = new AnimalKiller();// We create new instance of class AnimalKiller and assign to variable aKiller with is type of `AnimalKilleraKiller `
AnimalSaver aSaver = new AnimalSaver(); //
doTheRequiredOperation(aKiller);
doTheRequiredOperation(aSaver);
}
Example 2:
public void test() {
InterfaceOfPigKiller aKiller = new AnimalKiller();// We create new instance of class AnimalKiller and assign to variable aKiller with is type of `InterfaceOfPigKiller `
InterfaceOfPigKiller aSaver = new AnimalSaver(); //
doTheRequiredOperation(aKiller);
doTheRequiredOperation(aSaver);
}
The code example 1 and 2 are equally in scope of method doTheRequiredOperation. The difference is that in we assign once type to type and in the second we assign type to interface.
Conclusion
We can not create new object of abstract class or interface but we can assign object to interface or class type.