I'm learning Desgin patterns and come across very weird example in HERE. If we got a class:
public abstract class AbstractFactory {
abstract Color getColor(String color);
abstract Shape getShape(String shape) ;
}
which as we can see, has 2 types of methods which creates Objects: colors and shapes. This class is abstract so we have to create concrete implementation of this, so lets assume that we have:
public class ShapeFactory extends AbstractFactory {
#Override
public Shape getShape(String shapeType){
// I skip implementation to keep post brief
}
#Override
Color getColor(String color) {
return null; // It's useless method in this class!
}
}
and second implementation:
public class ColorFactory extends AbstractFactory {
#Override
public Shape getShape(String shapeType){
return null; // It's useless method in this class!
}
#Override
Color getColor(String color) {
// I skip implementation to keep post brief
}
}
And here comes my question, in both cases (concrete factories) there is an method that is completly useless and shoudn't be there, but as we created AbstractFactory class we have to implement both methods. Isn't it bad practice in programming to create useless methods in classes that don't need it? Should it be done in other way not as website suggest?
#Michael213 - Your concrete implementations are not correct. For sure they do not follow Abstract Factory pattern. Abstract factory talks about families of product. abstract factory sample (with my assumptions) will look like following code. your example using only one method will be misuse of pattern and will break soon.
I have already answer similar question please have a look to that also What are the real benefits of using the Abstract Factory in the following example, instead of the factory method?
public abstract class AbstractFactory {
abstract Color getColor(String color);
abstract Shape getShape(String shape) ;
}
/**
* CONCRETE FACTORY1
*/
class HighResolutionFactory extends AbstractFactory{
Color getColor(String color){
return new HighResolutionColor();
}
Shape getShape(String shape){
return new HighResolutionShape();
}
}
/**
* CONCRETE FACTORY2
*/
class LowResolutionFactory extends AbstractFactory{
Color getColor(String color){
return new LowResolutionColor();
}
Shape getShape(String shape){
return new LowResolutionShape();
}
}
class Color{} // ABSTRACT PRODUCT 1
class Shape{} // ABSTRACT PRODUCT 2
class HighResolutionColor extends Color{}// CONCRETE PRODUCT1 FACT 1
class HighResolutionShape extends Shape{}// CONCRETE PRODUCT2 FACT 1
class LowResolutionColor extends Color{}//...
class LowResolutionShape extends Shape{}
Yes, that tutorial doesn't seem the best in that regards.
It is not ideal although it still counts as a factory design pattern.
AbstractFactory is wrong. You do not have to think of a factory that makes different objects. It is right to make separate factories for each different type.
public interface AbstractColorFactory {
public Color getColor(String color);
}
public interface AbstractShapeFactory {
public Shape getShape(String shape);
}
public class ColorFactory implements AbstractColorFactory {
public Color getColor(String color) {
return ....
}
}
public class ShapeFactory implements AbstractShapeFactory {
public Shape getShape(String shape) {
return ....
}
}
Related
If the base class and sub class implements the same interface and the method implementation of the abstract method is provided in the base class then do we have to provide the implementation in sub class also?
Yes you can, and the implementation from subclass executes when you have initialisation paradigm
BaseClass v = new SubClass();
That's quite normal polymorphism/ovveriding.
Related : Can an interface extend multiple interfaces in Java?
do we have to provide the implementation in sub class also
No, you don't have to do it. If one class extends another, it already has all (public and protected) methods declared in parent class.
But you can provide a different implementation of this method. In this case the method from the parent class will be overriden.
There is no need of implementing the same interface in both parent and child classes as because if you are implementing it in parent class then child will also have the same method but if you want to override you can override it.
public interface Shape {
void draw();
}
class Parallelogram implements Shape {
public void draw() {
System.out.println("This is Parallelogram");
}
}
public class Square extends Parallelogram {
#Override
public void draw() {
System.out.println("This Parallelogram is Square");
}
public static void main(String args[0]) {
Square square = new Square();
square.draw();
}
}
//Output
This Parallelogram is Square
public class Rhombus extends Parallelogram {
public static void main(String args[0]) {
Rhombus rhombus = new Rhombus();
rhombus.draw();
}
}
//Output
This is Parallelogram
It should not be required as subclass already has the method implementation in base class
Lets say I had a simple inheritance structure like so:
class Shape {
int id;
}
class Circle extends Shape {
int radius;
}
class Square extends Shape {
int length;
}
class ToyBox {
List<Shape> shapes;
}
These objects cannot be augmented in any way (no adding methods/fields/accessors.change the file in any way) and should be treated as immutable/final. I have to return each of these shape objects to another part of the system I am working within with some extra information to go alongside each item. For example:
class extended Shape {
int id;
}
class ExtendedCircle extends ExtendedShape {
public Circle circle;
public Blah circleStuff;
public ExtendedCircle(Circle circle) {...}
}
class ExtendedSquare extends ExtendedShape {
public Square square;
public Blah squareStuff;
public ExtendedSquare(Square square) {...}
}
The only way I can think of accomplishing this task given a ToyBox of shapes is to iterate through the shapes list, do an instance of check and do a cast to circle, square etc. to then construct each of the corresponding "Extended" objects. This makes me a little uncomfortable so i am wondering if there is another way to design such a system?
If you need to avoid casting and using instanceof operator you probably would like to consider using Vistor design pattern. Applying it to your example if might looks as following:
class Shape {
int id;
public void visitingShape(ToyBox box) {
box.visitingShape(this);
}
}
class Circle extends Shape {
int radius;
public void visitingShape(ToyBox box) {
box.visitingCircle(this);
}
}
class Square extends Shape {
int length;
public void visitingShape(ToyBox box) {
box.visitingSquare(this);
}
}
class ToyBox {
List<Shape> shapes;
public visitingShape(Shape shape) {
// Do logic related to the shape
}
public visitingCircle(Circle shape) {
// Do logic related to the circle
}
public visitingSquare(Square shape) {
// Do logic related to the square
}
}
I can propose an approach which is closer to pattern-matching. It doesn't solve the problem using inheritance, but it should give the same advantages as a visitor pattern without the heavyweight aspect of it.
Simply introduce a ShapeType enumeration, make each shape return its type and use a switch-case structure to implement your logic. Might be more readable.
It seems like you're in a pretty tough spot not owning the shape classes but I think you could add shape proxies. It adds an additional layer but provides the ability to extend the shapes as well as additional control over the interface if you'd need it.
Let's say, given a Shape as follows:
public class Shape {
public void doSomethingWithShape() {}
}
You provide a ShapeProxy like so (implementing the Shape interface and providing a proxy into it):
public class ShapeProxy extends Shape implements IShapeProxy {
// Optional
#Override
public void doSomethingWithShape() {
// Do something extra if needed.
}
// From IShapeProxy
#Override
public ExtendedShape getExtended() {
return new ExtendedShape(this);
}
}
Likewise, you would have proxies for each additional shape:
public class CircleProxy extends Circle implements IShapeProxy {
#Override
public ExtendedCircle getExtended() {
return new ExtendedCircle(this);
}
}
And, of course, you could use it like this:
public static void main(String[] args) {
List<IShapeProxy> shapes = new ArrayList<>();
shapes.add(new ShapeProxy());
shapes.add(new CircleProxy());
shapes.add(new SquareProxy());
List<ExtendedShape> extendedShapes = new ArrayList<>();
shapes.forEach(s -> extendedShapes.add(s.getExtended()));
}
I would prefer it this way but if you couldn't change the type of List then you could still shove them in as Shapes and cast to get the extended type. Still, it's a common cast that wouldn't require knowledge about the type of shape at hand.
If that seems like too much or if you'd like to separate the extending from the proxy, you can combine the proxy idea with Dici's suggestion and add a type like so (changes to the interface not shown):
public enum ShapeType {
SHAPE, CIRCLE, SQUARE
}
public class CircleProxy extends Circle implements IShapeProxy {
// From IShapeProxy
#Override
public ShapeType getType() {
return ShapeType.CIRCLE;
}
}
// And...
for (IShapeProxy proxy : shapes) {
switch (proxy.getType()) {
case SHAPE:
// Build the extended type.
break;
...
}
}
}
As you all know that the AbstractFactory helps creating object without knowledge of creation process. But the complexity of the pattern will increase by the time, when new factory is added or large modifications are made within the factory class. This will require a heavy change on abstract factory creator class.
I used to use AbstractFactory, but with my own modification & it's like: Replace abstract factory creator class with empty interface, which will be implemented by factory classes. Then cast returned object from FactoryCreator class to the real factory I want. This worked, but I wonder if this breaks the pattern or is it a bad practice on the pattern or does it have any drawback that would lead to the same complexity in the future development?
Below is a very simple implementation of the pattern that I took from the book & my modifications as well:
Shape factory:
public interface Shape {
void draw();
}
public class Circle implements Shape {
#Override
public void draw() {
// Draw circle
}
}
public class Rectangle implements Shape {
#Override
public void draw() {
// Draw rectangle
}
}
public class ShapeFactory implements IFactory {
public Shape getShape(String shape) {
if (shape.equalsIgnoreCase("CIRLE")) {
return new Circle();
} else if (shape.equalsIgnoreCase("RECTANGLE")) {
return new Rectangle();
}
return null;
}
}
//public class ShapeFactory extends AbstractFactory {
// #Override
// public Color getColor(...) {
// //
// }
// #Override Shape getShape(...) {
// //
// }
//}
Color factory:
public interface Color {
void fill();
}
public class Red implements Color {
#Override
public void fill() {
// Fill red
}
}
public class Green implements Color {
#Override
public void fill() {
// Fill green
}
}
public class ColorFactory implements IFactory {
public Color getColor(String color) {
if (color.equalsIgnoreCase("RED")) {
return new Red();
} else if (color.equalsIgnoreCase("GREEN")) {
return new Green();
}
}
}
//public class ColorFactory extends AbstractFactory {
// #Override
// public Color getColor(...) {
// //
// }
// #Override Shape getShape(...) {
// //
// }
//}
Factory creator interface:
public interface IFactory { }
//public abstract class AbstractFactory {
// abstract Color getColor(String color);
// abstract Shape getShape(String shape) ;
//}
Factory creator:
public class FactoryCreator {
public static IFactory getFactory(String factoryName) {
if (factoryName.equalsIgnoreCase("SHAPE")) {
return new ShapeFactory();
} else if (factoryName.equalsIgnoreCase("COLOR")) {
return new ColorFactory();
}
return null;
}
}
Usage:
public class demo {
ShapeFactory shapeFactory = (ShapeFactory)FactoryCreator.getFactory("SHAPE");
ColorFactory colorFactory = (ColorFactory)FactoryCreator.getFactory("COLOR");
shapeFactory.getShape("CIRCLE").draw();
shapeFactory.getShape("RECTANGLE").draw();
colorFactory.getColor("RED").fill();
colorFactory.getColor("GREEN").fill();
}
So the question in essence boils down to difference between abstract class and interface.
There are many sources on this discusion:
see here
What you need to understand about the patterns is that they are designed to be template for solution. It will happen rarely that you can copy paste pattern with zero modification and expect to fit your problem perfectly.
As for your question, can you implement AbstractFactory pattern with a FactoryCreator interface instead of abstract class ?
Surely you can, this is an implementation detail which does not break the intent of the pattern.
Abstract Factory offers the interface for creating a family of related objects, without explicitly specifying their classes.
Edit
You are looking at one specific implementation of this pattern in which author decided to implement the template with abstract class.
Design patterns are not a guarantee to to the right thing... you have to use your head first...
history showed that many people had a certain problem with [xxx] and a lot of people could solve the problem with Design-Pattern [yyy]. That's how desgin pattern evoveld and how they are defined.
You cannot say i'll implement this (or that) pattern and i'll have no problems anyway. you have to think, describe your problem and see if this pattern would help you to design your architecture.
Obviously: your programm implementation is so simple that abstractFactory is overhead, and you already solved that with using mere interfaces.
ok, let's speak the obvoius:
AbstractFactory is not the solution to your problem:
first: define your problem: i want to create parametrized objects in a simple way. a) parametrized with shape and color and b) simple way
possible solution: factory-methode (think: you have the interface Shape with two implementations and the interface Color with two implementations)
public ShapeFactory{
public static Shape create(String shape){
if ("CICRCLE".equals(shape)) //your code from above
}
}
and a Color factory
public ColorFactory{
public static Color createColor(String color){
if("GREEN".equals(color) ) // your code from above
}
}
using these design pattern you can solve your problem as defined above... (you can make one factory wich provides factory-methods for both interfaces, if you want to make it even shorter)
As per my understanding in the above problem, one wants to create a shape and then fill color in it. If thats the case one can make it bit better by adding Builder pattern on top of factory.
class ShapeBuider
{
private String color;
private String shape;
/**
* #param color the color to set
*/
public void setColor(String color) {
this.color = color;
}
/**
* #param shape the shape to set
*/
public void setShape(String shape) {
this.shape = shape;
}
public void build()
{
// create shape
// create color
// fill shape with color
}
public Object get()
{
// return the created object in build method here.
return null;
}
}
This builder approach will make sure that the right color is applied to right shape.
I know this is a very simple question, but I have been working in Python for quite a long time and now that I must go back to Java, I seem to have problems changing the chip and wrapping my head around Java's basic polymorphism.
Is it possible to overwrite (implement, to be precise) a class' abstract method in Java using one of the inherited classes as argument?
Let me explain with a very simple example (following the "almost official" example with shapes)
class Shape {}
class Circle extends Shape {}
class Triangle extends Shape {}
abstract class ShapeDrawer {
abstract void draw(Shape s);
}
class CircleDrawer extends ShapeDrawer {
void draw(Circle c){
System.out.println("Drawing circle");
}
}
Is there any way of having Java identifying the draw method in the CircleDrawer class as the implementation of the abstract draw in ShapeDrawer? (The Circle class extends from Shape after all)
Otherwise put: What I'd like is that the draw method of the CircleDrawer class accepts only instances of type Circle, but at the same time, I'd like to tell the Java compiler that the void draw(Circle c) is actually the implementation of the abstract method abstract void draw(Shape s) located in its parent class.
Thank you in advance.
You can solve your problem by means of generics:
public abstract class ShapeDrawer<T extends Shape> {
public abstract void draw(T shape);
}
public class CircleDrawer extends ShapeDrawer<Circle> {
public void draw(Circle circle) { ... }
}
You can't and there is a very good reason why you can't. Take this declaration
public abstract class ShapeDrawer {
public abstract void draw(Shape s);
}
Now take some code that receives a ShapeDrawer and tries to use it:
public void foo(ShapeDrawer drawer, Shape shape) {
drawer.draw(shape);
}
This code should work because the declaration of ShapeDrawer promises that whoever implements it will provide a method called draw() and that method can deal with any Shape.
But if you were allowed to do this:
public class CircleDrawer extends ShapeDrawer {
public void draw(Circle c) {...}
}
That would no longer hold true, your CircleDrawer would be unable to satisfy the promise that it can deal with any Shape.
However imagine this declaration:
public abstract class ShapeCreator {
public abstract Shape create();
}
public class CircleCreator extends ShapeCreator {
public Circle create() {...}
}
Would this work?
Yes, it would(provided that you use Java 5 or later), because unlike the first declaration, what ShapeCreator promises is that it will have a method called create(), which will return a Shape. Since Circle is a Shape, a subclass of ShapeCreator can decide to return only Circles, no promises are broken.
So how do you achieve what you want? See loonytune's answer :)
Not technically, but you can do a hack around it for the functionality you specified.
public abstract ShapeDrawer {
public abstract void draw(Shape s);
}
public CircleDrawer extends ShapeDrawer {
public void draw(Shape s){
if (s instanceof Circle) {
System.out.println("Drawing circle");
}
}
}
No, Java method signatures must match exactly, you can't use subtypes, or you'll overload a method instead of overriding it.
You can return a subtype, but that's it, and return types aren't part of a method signature.
What I try to accomplish is to invoke the Interface of a specific class.
I use a Enum to fill in the .class and to get the Interface of that Class.
So how can I return the interface?
I would like to avoid reflection if possible.
Thanks in advance.
public interface GameInterface {
void start();
void sop();
}
public enum Game{
MINESWEEPER(MineSweeper.class),
MARIO(Mario.class);
private Class c;
public Game(Class c) {
this.c = c;
}
public GameInterface getGameInterface() {
// return Interface of the class
// So I can call for instance MINESWEEPER.getGameInterface().start()
// At this momement I use return:
// ((GamemodeInterface)this.c.getDeclaredMethod("getInstance", new Class[0]).invoke(null, new Object[0]));
// *MineSweeper and Mario are Singleton, thats why getInstance
}
}
Clarification:
The main goal is to acces Start() and Stop() methods at MineSweeper and Mario class.
The usage should be something like: MINESWEEPER.getGameInterface().start()
But at this moment I don't know a solid solution to get the Interface with knowing of the .class.
A better idea:
Implement GameInterface to each Game of your class with implying name of your choice.
Declare enum with abstract function createGame and return with the instance of the Game class you are expecting with implementation of this createGame function to each enum constant:
class MineSweeper implements GameInterface
{
// your code
}
class Mario implements GameInterface
{
// your code
}
public enum GameType
{
MINESWEEPER
{
public GameInterface createGame()
{
return new MineSweeper();
}
},
MARIO
{
public GameInterface createGame()
{
return new Mario();
}
}
public abstract GameInterface createGame();
}
If you intended to use singleton pattern, although i could not be so sure from your question but as #GaborSch has suggested: you could make use of MineSweeper.getInstance() function inside the createGame() of enum constants. However, try thinking to use an enum while implementing a Singleton too, as is suggested in Effective Java book with detail explanation.