It may look similar to my question. I have a simple animal factory.
public class AnimalFactory {
public Animal getAnimal(String type) {
if ("canine".equals(type)) {
return new Dog();
} else {
return new Cat();
}
}
}
and class for
public interface Animal {
void makeSound();
}
public class Dog extends Animal {
void makeSound() {
}
}
public class Dog extends Animal {
void makeSound() {
}
}
I have some doubts. Does AnimalFactory violate the dependency inversion principle? Is it possible to unit test AnimalFactory without making calls to the actual Dog and Cat classes or do I have to refactor my code?
You're not violating the dependency inversion principle if there are no dependencies to inject.
In any case the Factory is a creational design pattern and you should test that it does indeed create (instantiate) the right things.
Yes, you should test that it does return objects where instanceof Dog and instanceof Cat are true.
If you must test your factory without actually calling the constructors of Dog and Cat (due to the initialization that they do), I suggest refactoring the factory class like this:
public class AnimalFactory {
public Animal createAnimal(String type) {
if ("canine".equals(type)) {
return createDog();
} else {
return createCat();
}
}
Dog createDog() { return new Dog(); }
Cat createCat() { return new Cat(); }
}
And the test would look like this:
public class AnimalFactoryTest {
#Test
public void testCreateDog() throws Exception {
AnimalFactory mockFactory = mock(AnimalFactory.class);
when(mockFactory.createAnimal(anyString())).thenCallRealMethod();
mockFactory.createAnimal("canine");
verify(mockFactory).createDog();
}
#Test
public void testCreateCat() throws Exception {
AnimalFactory mockFactory = mock(AnimalFactory.class);
when(mockFactory.createAnimal(anyString())).thenCallRealMethod();
mockFactory.createAnimal("cat");
verify(mockFactory).createCat();
}
}
Incidentally, the naming convention for Factory pattern methods are createXyz rather than getXyz.
Good luck.
Related
I tried to implement a function in a base class which using the function of the childs (defiend as a abstract function in the base class). I think an example will demonstrate the problem in the best way.
abstract class Animal{
public void doSomthing(){
this.sound();
}
protected abstract void sound();
}
class Dog extends Animal{
#Override
protected void sound(){
System.out.println("WAF");
}
}
now when I tried to get the element in run time (by factory method which looks like: Animal factory method("Dog);) and call to the doSomthing method I got exception because it goes to the abstract method, my question is if there is any way the bypass this or another solution for this problem.
class myMain
{
public static void main(String[]args)
{
Animal doggo = new Dog(); // create object for dog
doggo.animalSound(); // call the sound for dog
}
}
class Animal
{
public void animalSound()
{
System.out.println("The animal makes a sound");
}
}
class Dog extends Animal
{
public void animalSound()
{
System.out.println("The Dog Says bow wow! ");
}
}
I do not see any problem with the approach you have mentioned in the description of your question. Maybe you are doing some other mistake. Check the following working code:
abstract class Animal {
public void doSomthing() {
sound();
}
protected abstract void sound();
}
class Dog extends Animal {
#Override
protected void sound() {
System.out.println("WAF");
}
}
class AnimalFactory {
static Animal animal;
public static Animal factoryMethod(String animalName) {
if ("Dog".equals(animalName)) {
animal = new Dog();
}
return animal;
}
}
class Main {
public static void main(String[] args) {
Animal animal = AnimalFactory.factoryMethod("Dog");
animal.sound();
}
}
Output:
WAF
The call to child class method from super class can be done.
Refer code snippet mentioned in below link:
Can a Parent call Child Class methods?
I have several classes with differently object type cat, dog and horse. I have
one root class where is method doSomethig with only one parameter which I want to call in rest of classes. How to write the method without type conflict. This is only example.
Cat cat;
Dog dog;
Horse horse;
protected void doSomething(one parameter){
cat.doMeow();
dog.doBark();
horse.run();
}
Why not to extend parent class Animal where there would be doSomething(one parameter) and then in subclasses call super() ?
If I understand you right, the signature is fixed for just one parameter. But you need to have access to cat, dog and horse? In that case, you need to adjust one to be a parameter object.
(Also, it should start with an upper case letter, as general accepted code style)
public class one
{
private Cat cat;
private Dog dog;
private Horse horse;
public one(Cat cat, Dog dog, Horse horse)
{
this.cat = cat;
this.dog = dog;
this.horse = horse;
}
public Cat getCat()
{
return this.cat
}
// getDog(), getHorse()
}
Then use the getter methods in the doSomething method
protected void doSomething(one parameter){
parameter.getCat().doMeow();
parameter.getDog().doBark();
parameter.getHorse().run();
}
Calling it like:
public void myMethod()
{
one animals = new one(new Cat(), new Dog(), new Horse());
doSomething(animals); // if same class or myInstance.doSomething(animals) if another class
}
A brute force solution would be to pass an Object, e.g. of type Animal and check the type in the method, and call the appropriate method based on the result of the type check:
protected void doSOmething(Animal an Animal) {
if( anAnimal instanceof Horse)
((Horse) anAnimal).run();
else if( anAnimal instanceof Dog )
((Dog) anAnimal).bark();
else ...
}
However, this is considered to be bad style, because the method has too much knowledge about Horses, Dogs, and such.
It would be better if Animal had an abstract method doDefaultAction() which is overwritten by the Horse as a call to run(), by the dog as a call to bark(), and so on.
abstract class Animal {
abstract void doDefaultAction(Animal anAnimal);
}
class Horse extends Animal {
#Override
void doDefaultAction(Animal anAnimal) {
((Horse) anAnimal).run();
}
void run() { /* do some running */ }
}
In your method doSomething() you would simply call anAnimal.doDefaultAction() without need to know what the default action for the animal might be.
If the abstract Animal class does not do something else you might also consider to use an interface Animal instead of a class.
You could create a common interface and call the interface method. For example:
public interface Animal {
public void act();
}
public class Cat implements Animal {
public void doMeow() { /* ... */ }
#Override
public void act() {
doMeow();
}
}
public class Dog implements Animal {
public void doBark() { /* ... */ }
#Override
public void act() {
doBark();
}
}
Then the doSomething method could polymorphically call the act method:
protected void doSomething(Animal animal) {
animal.act();
}
Depending on which object is passed (e.g. Cat or Dog), the behavior of doSomething will change.
Assuming this is the classic OO inheritance example. A simple solution works like this:
public class AnimalExample {
interface Animal {
void action();
}
public static class Cat implements Animal{
#Override
public void action() {
System.out.println("meow");
}
}
public static class Dog implements Animal{
#Override
public void action() {
System.out.println("bark");
}
}
public static class Horse implements Animal{
#Override
public void action() {
System.out.println("run");
}
}
static void doSomething(Animal animal){
animal.action();
}
public static void main(String[] args) {
Cat cat = new Cat();
Dog dog = new Dog();
Horse horse = new Horse();
doSomething(cat);
doSomething(dog);
doSomething(horse);
}
}
Assume we have a class Animal, with subclasses as cat, eagle
Now I have a method:
public void process(Animal animal) {
if (animal instanceof Cat) {
if (!animal.meow()) {
throw exception("cat does not meow");
} else {
animal.feedFish();
}
}
if (animal instanceof eagle) {
if (!animal.fly()) {
throw exception("eagle does not fly");
} else {
animal.checkMaxFlightAltitude();
}
}
}
Here cat has 2 methods meow and feedfish which are completely different than eagle's methods fly and checkmaxflight
Most design patterns revolve around assumptions that subclasses have a common method like Shape draw() inherited by circle draw and square draw
Is there some way to do validations on subclasses, such as cat and eagle without instanceof check ?
Any good design pattern ( assuming subclasses dont share a method in base class ? )
You could have an abstract process method in Animal and implement it in the subclasses:
class Animal {
protected abstract void process();
public static void process(Animal a) { a.process(); }
}
class Cat {
void process() {
if (!meow()) throw exception("cat does not meow");
else feedFish();
}
public boolean meow() { ... }
public void feedFish() { ... }
}
You could use double dispatch by employing a visitor.
Example:
public class Animal {
public abstract void accept(AnimalVisitor v);
public boolean meow() {return false;}
public boolean fly() {return false;}
public void feedFish() {};
public void checkMaxFlightAltitude() {};
}
public class Cat extends Animal {
public void accept(AnimalVisitor v) {
v.visitCat(this);
}
public boolean meow() {return true;}
}
public class Eagle extends Animal {
public void accept(AnimalVisitor v) {
v.visitEagle(this);
}
public boolean fly() {return true;}
}
public interface AnimalVisitor {
void visitEagle(Eagle eagle);
void visitCat(Cat cat);
}
public class AnimalVisitorExample implements AnimalVisitor {
public void visitEagle(Eagle eagle) {
eagle.checkMaxFlightAltitude();
}
public void visitCat(Cat cat) {
cat.feedFish();
}
}
Animal animal = new Cat();
animal.accept(new AnimalVisitorExample());
(1) Is there some way to do validations on subclasses, such as cat and eagle without instanceof check ?
yes, there is. You could define a "validate" method (abstract in "Animal" class) and implement it in the specific subclasses. Depending on the validation result (e.g. exception / problem list) you can have the validate method throw some kind of "InvalidContentException" or provide the method call with an "ErrorHandler" that is informed about the bad things of an instance.
(2) assuming that the subclasses don't share a method in the base class: well, that one is a bit counter intuitive. On one hand you want to be able to do something on an "Animal", yet you don't want to define that capability on it?
You could define a Validator class that has separate validation methods (on for each kind of "Animal" subclass). That would eliminate the instanceof checks, however you would never be able to pass this Validator class other "Animals" (such as "Dog"), only "Cat" and "Eagle" (or subclasses thereof). You might also want to consider what you want to happen when passing subclasses of "Cat": are all sublasses of Cat validated in the same way or is there subclass specific behavior (like color, size, ...) for the different cat classes?
--> I think you should ask yourself if you want to be able to validate animals in general. Without having insight into your problem domain (which might have reasons not to do it), I'd recommend to have a "validate" method on the animal. You could also go for a visitor pattern, but that requires the Animal to have a "accept(AnimalVisitor visitor)" method and is slightly more code to write (presumably more than you want to)
This is when polymorphism comes in handy.
abstract class Animal {
abstract public void process(Animal animal);
}
class Cat extends Animal {
#Override
public void process(Animal animal) {
if (!this.meow()) {
throw exception("cat does not meow");
} else {
this.feedFish();
}
}
}
class Eagle extends Animal {
#Override
public void process(Animal animal) {
if (!this.fly()) {
throw exception("eagle does not fly");
} else {
this.checkMaxFlightAltitude();
}
}
}
I'm working on a problem where different animal types implement the same talk() method from Animal interface.
If you look at getAnimal() method, you can see that, when a new kind of animal is added to the program, inside of that method has to be changed as well.
I want to add new animals just by subclassing Animal without changing anything in the already existing classes.
For example, add an animal "Dog", criteria="loyal"; talk="woof".
Could you tell me, how it is possible? Below is my code:
interface Animal {
public void talk();
}
class Lion implements Animal {
#Override
public void talk() {
System.out.println("ROARRRRR");
}
}
class Mouse implements Animal {
#Override
public void talk() {
System.out.println("SQUEEEEEAK");
}
}
class Bison implements Animal {
#Override
public void talk() {
System.out.println("BELLOWWWWW");
}
}
class AnimalType {
public static Animal getAnimal(String criteria) {
// I refactor this method
if (criteria.equals("small")) {
return new Mouse();
} else if (criteria.equals("big")) {
return new Bison();
} else if (criteria.equals("lazy")) {
return new Lion();
}
return null;
}
}
public class AnimalExamples {
public static void main(String[] args) {
AnimalType.getAnimal("small").talk();
AnimalType.getAnimal("big").talk();
AnimalType.getAnimal("lazy").talk();
// how to add an animal "Dog" here, criteria="loyal"; talk="woof"
AnimalType.getAnimal("loyal").talk();
try {
AnimalType.getAnimal("small").talk();
} catch (Exception ex) {
System.out.println("Animal does not exists");
}
}
}
I searched on google, understood it can be done by reflection. But do not know how. If possible, could you help me with this, please? Thanks in advance!
Just so you know runtime class generation is extremely complex and not something recommended for beginners to the language. This would be an excellent scenario to use a map an anonymous classes.
class AnimalType {
private static final Map<String, Animal> animals = new HashMap<String, Animal>();
static {
// Populating map with default animals
addAnimal("big","BELLOWWWWW"); // bison
addAnimal("small","SQUEEEEEAK"); // mouse
addAnimal("lazy","ROARRRRR"); // lion
addAnimal("loyal","WOOF "); // dog
}
public static void addAnimal(String criteria, final String sound) {
// Assigning a anonymous implementation of animal to the given criteria
animals.put(criteria, new Animal() {
#Override
public void talk() {
System.out.println(sound);
}
});
}
public static Animal getAnimal(String criteria) {
// Returning an animal from the animals map
return animals.get(criteria);
}
}
If you really do insist on true runtime class generation or if you're curious how it works, check out ByteBuddy.
Old question, but here is how to create class... For me the easy way is to use Javassist.
I created a small example here: http://hrabosch.com/2018/04/08/generate-class-during-runtime-with-javassist/
But here is main point:
public static Class generateClass(String className, String methodName, String methodBody)
throws CannotCompileException {
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.makeClass(className);
StringBuffer method = new StringBuffer();
method.append("public void ")
.append(methodName)
.append("() {")
.append(methodBody)
.append(";}");
cc.addMethod(CtMethod.make(method.toString(), cc));
return cc.toClass();
}
So what I did... Via Javassist I made a class in ClassPool. Also I added a method inside this class and via reflection I invoked it.
Hope it helps.
Just keep on mind whatever you want to use in generated class, there
are NOT imports, so you have to use fully-qualified names.
Java doesn't support creating a class at runtime. However there are really better ways of achieving what you want here. I'll propose two.
Firstly, you could create an AnimalType class that contains all the shared behaviour about a species. You could then have an Animal class that takes an AnimalType as a constructor parameter.
Secondly, you could use a prototype design pattern. In this case the Animal class would need a clone method to create a new animal from the prototype. The factory class could then have a list of the prototypes and use whatever logic you desire to choose the correct prototype to clone.
Comment below if you want further details or sample code for either of these options.
you have to define the dog class
class Dog implements Animal {
#Override
public void talk() {
System.out.println("woof");
}
}
and add the if else to AnimalType
} else if ("loyal".equals(criteria)) {
return new Dog();
}
I am having a problem with Factory pattern when it use with Inheritance,
This is my code
public class Animal {
public int numberOfLegs() { return 2 ;}
}
public class Cat extends Animal {
public String getSound() {return "Maaaw";}
}
public class Dog extends Animal {
public String getSound() {return "woof";}
}
public class AnimalFactory {
public Animal getAnimal(String name){
Animal an= null ;
if(name=="cat"){an = new Cat();}
else if(name=="dog"){an=new Dog();}
return an ;
}
}
public class FactoryDemo {
public static void main(String[] args) {
AnimalFactory anmF=new AnimalFactory();
Animal anm=anmF.getAnimal("cat") ;
System.out.println("legs : "+anm.numberOfLegs()); // working fine
System.out.println("sound : "+anm.getSound()); // giving error
}
}
When I run this, I can't go to the getSound() method. It giving a error.
This'll work fine if I define the Animal class as Abstract class,
But I want to how to deal Factory pattern such a situation like this.
You need to add an abstract method for getSound
public abstract class Animal {
public int numberOfLegs() { return 2 ;}
public abstract String getSound();
}
Change your code to:
public abstract class Animal {
public int numberOfLegs() {
return 2;
}
public abstract String getSound();
}
public class Cat extends Animal {
public String getSound() {
return "Maaaw";
}
}
public class Dog extends Animal {
public String getSound() {
return "woof";
}
}
public class AnimalFactory {
public Animal getAnimal(String name) {
Animal an = null;
if ("cat".equals(name)) {
an = new Cat();
} else if ("dog".equals(name)) {
an = new Dog();
}
return an;
}
}
You shall add abstract method, and use equals in your factory method instead of using == on Objects.
The code you included, is nothing like a Factory anything. If you refer to the Factory Method Pattern then, what you implemented as part of your OP is an incorrect implementation. There are two "Factory" code designs, one is the Factory Method Pattern I indicated before (your code is definitely not that) and the Factory recommended in the Effective Java book, which is the design of choice for the Java JDK i.e. the valueOf or create* methods.