I am studying about design principles and design patterns. I have implemented an Abstract factory pattern as per my understanding. The scenario I have considered is as follows :
- There is an organization 'DrawingStandards.ltd' for setting standard rules for drawing.
- There are two Other organizations 'Shape.ltd' and 'EnhancedShape.ltd' which provides Shapes as per the rules set by the 'DrawingStandards.ltd'.
- There is another organization 'Graphics.ltd' which uses the Shapes implemented by Shape.ltd and 'EnhancedShape.ltd'.
Code from DrawingStandard.ltd
Drawable.java
package com.drawing.drawable; /** * Interface for DrawableFactory, implement this for any new Drawable shape. * * @author [email protected] * */ public interface Drawable { /** * draws the concrete drawable. */ public void draw(); }
DrawableFactory.java
package com.drawing.drawable.factory; import com.drawing.drawable.Drawable; /** * Abstract Factory to create the concrete drawables based on the input. Extend * this class to provide concrete implementation for creation of any new product * * @author [email protected] * */ public abstract class DrawableFactory { /** * * @param factory * @return concrete drawable object as created by the factory */ public final Drawable getDrawable(DrawableFactory factory) { return factory.createDrawable(); } /** * * @return Drawable created by the concrete factory. */ protected abstract Drawable createDrawable(); }
These classes have been released via jar.
Now Code from Shapes.ltd
Circle.java
package com.shape.drawables; import com.drawing.drawable.Drawable; /** * Drawable class representing a Circle. * * @author [email protected] * */ public class Circle implements Drawable { private int radius; /** * Takes radius of the circle as input * * @param radius */ public Circle(int radius) { this.radius = radius; } /** * provides concrte implementation for draw method specific to circle. It * uses the length of the radius passed in the constructor to draw the * circle. */ @Override public void draw() { System.out.println("Drawing the circle with radius = " + radius); } }
Square.java
package com.shape.drawables; import com.drawing.drawable.Drawable; /** * Drawable for drawing a square. * * @author [email protected] * */ public class Square implements Drawable { private int sideLength; /** * Takes the input as length of the side * * @param sideLength */ public Square(int sideLength) { this.sideLength = sideLength; } /** * provides concrete implementation to the draw method, specific to square, * defined in Drawable. interface. It uses the length of the side passed in * the constructor to draw the square. */ @Override public void draw() { System.out.println("Drawing a Square with side length =" + sideLength); } }
Triangle.java
package com.shape.drawables; import com.drawing.drawable.Drawable; /** * Drawable representing a Triangle * * @author [email protected] * */ public class Triangle implements Drawable { private int sideOneLength; private int sideTwoLength; private int sideThreeLength; /** * takes input for the three sides. * * @param sideOneLength * @param sideTwoLength * @param sideThreeLength */ public Triangle(int sideOneLength, int sideTwoLength, int sideThreeLength) { this.sideOneLength = sideOneLength; this.sideTwoLength = sideTwoLength; this.sideThreeLength = sideThreeLength; } /** * provides concrete implementation to draw method specific to the circle. * * It uses the length of the three sides passed in the constructor to draw * the triangle. */ @Override public void draw() { System.out.println("Drawing a Triangle with side one length = " + sideOneLength + " side two length = " + sideTwoLength + " side three length = " + sideThreeLength); } }
Now the factory classes
CircleFactory.java
package com.shape.drawables.factories; import com.drawing.drawable.Drawable; import com.drawing.drawable.factory.DrawableFactory; import com.shape.drawables.Circle; /** * Concrete Factory for Cicle provided by Shape.ltd * * @author [email protected] * */ public class CircleFactory extends DrawableFactory { private int radius; /** * takes length radius as parameter * * @param radius */ public CircleFactory(int radius) { this.radius = radius; } @Override protected Drawable createDrawable() { return new Circle(radius); } }
SquareFactory.java
package com.shape.drawables.factories; import com.drawing.drawable.Drawable; import com.drawing.drawable.factory.DrawableFactory; import com.shape.drawables.Square; /** * Concrete factory for Square.by Shape.ltd * * @author [email protected] * */ public class SquareFactory extends DrawableFactory { private int sideLength; /** * takes the length of the side of the square * * @param sideLength */ public SquareFactory(int sideLength) { this.sideLength = sideLength; } @Override protected Drawable createDrawable() { return new Square(sideLength); } }
TriangleFactory.java
package com.shape.drawables.factories; import com.drawing.drawable.Drawable; import com.drawing.drawable.factory.DrawableFactory; import com.shape.drawables.Triangle; /** * Concrete implementation of Factory class for Triangle * * @author [email protected] * */ public class TriangleFactory extends DrawableFactory { private int sideOneLength; private int sideTwoLength; private int sideThreeLength; /** * Takes the length of three sides as parameter * * @param sideOneLength * @param sideTwoLength * @param sideThreeLength */ public TriangleFactory(int sideOneLength, int sideTwoLength, int sideThreeLength) { this.sideOneLength = sideOneLength; this.sideTwoLength = sideTwoLength; this.sideThreeLength = sideThreeLength; } @Override protected Drawable createDrawable() { return new Triangle(sideOneLength, sideTwoLength, sideThreeLength); } }
The code from EnhancedShapes.ltd
Similar classes as provided by Shapes.ltd (Circle.java,Triangle.Java,Square.java and the corresponding factory classes.) under the package
package com.enhancedshape.drawables
andpackage com.enhancedshape.drawables.factories;
Now the code from 'Graphics.ltd' Using the shapes implemented by two vendors above.
ShapePainter.java
package com.graphichs; import com.drawing.drawable.Drawable; import com.drawing.drawable.factory.DrawableFactory; /** * Fetches the best factory as per the resources availability and provides the * shape * * @author [email protected] * */ public class ShapePainter { private static long MIN_MEMORY_FOR_ENHANCED_SHAPE = 20796757; /** * Returns the best Square as per the resources available * * @param sideLength * @return Square */ public Drawable getSquare(int sideLength) { DrawableFactory factory = null; if (Runtime.getRuntime().freeMemory() < MIN_MEMORY_FOR_ENHANCED_SHAPE) { factory = new com.shape.drawables.factories.SquareFactory(sideLength); } else { factory = new com.enhancedshape.drawables.factories.SquareFactory(sideLength); } return DrawableFactory.getDrawable(factory); } /** * Returns the best Circle as per the resources available * * @param radius * @return Circle */ public Drawable getCircle(int radius) { DrawableFactory factory = null; if (Runtime.getRuntime().freeMemory() < MIN_MEMORY_FOR_ENHANCED_SHAPE) { factory = new com.shape.drawables.factories.CircleFactory(radius); } else { factory = new com.enhancedshape.drawables.factories.CircleFactory(radius); } return DrawableFactory.getDrawable(factory); } /** * Returns the best Triangle as per the resources available * * @param sideOneLength * @param sideTwoLength * @param sideThreeLength * @return Triangle */ public Drawable getTriangle(int sideOneLength, int sideTwoLength, int sideThreeLength) { DrawableFactory factory = null; if (Runtime.getRuntime().freeMemory() < MIN_MEMORY_FOR_ENHANCED_SHAPE) { factory = new com.shape.drawables.factories.TriangleFactory(sideOneLength, sideTwoLength, sideThreeLength); } else { factory = new com.enhancedshape.drawables.factories.TriangleFactory(sideOneLength, sideTwoLength, sideThreeLength); } return DrawableFactory.getDrawable(factory); } }
DriverProgram.java
package com.graphichs; import com.drawing.drawable.Drawable; public class DriverProgram { public static void main(String[] args) { ShapePainter shapePainter = new ShapePainter(); Drawable circle = shapePainter.getCircle(20); Drawable square = shapePainter.getSquare(30); circle.draw(); square.draw(); } }
Please provide your valuable review feedback.