Reputation: 558
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 .
Upvotes: 2
Views: 206
Reputation: 5101
This extends Avi's answer and addresses the comments.
The points of the code:
abstract
base class to emphasize IS A relationshipsabstract
class is as much a interface (little "i") as much as a Interface
(capital "I") is.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(); }
Upvotes: 1
Reputation: 30875
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.
Upvotes: 0
Reputation: 21866
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
.
Upvotes: 3