I'm looking for ideas on the best way to refactor this scenario (better design, minimal effort).
Starting from the following example abstract class (actual has many more fields, methods and abstract methods) :
abstract class Car
{
private int manufactureYear;
// ... many more fields that are hard to clone
public Car(int manYear)
{
this.manufactureYear = manYear;
}
abstract public Color getColor();
abstract public int getNumCylinders();
}
There are so many child classes (say 100) that extend this class. These child classes are considered like 'specs' for the cars. Here are two examples :
class CarOne extends Car
{
private static Color COLOR = Color.Red;
private static int CYLINDERS = 4;
public CarOne(int manYear)
{
super(manYear);
}
public final Color getColor();
{
return COLOR;
}
public final int getNumCylinders()
{
return CYLINDERS;
}
}
class CarOneThousand extends Car
{
private static Color COLOR = Color.Black;
private static int CYLINDERS = 6;
public CarOneThousand(int manYear)
{
super(manYear);
}
public final Color getColor();
{
return COLOR;
}
public final int getNumCylinders()
{
return CYLINDERS;
}
}
During runtime car objects get instantiated and used:
CarOne carObject = new CarOne(2009);
carObject.getColor();
carObject.getNumCylinders();
However, after getting some external data, I discover that the car was repainted and the engine changed. The new specs for the car become:
class ModCar extends Car
{
private static Color COLOR = Color.Blue;
private static int numCylinders = 8;
public ModCar (int manYear)
{
super(manYear);
}
public final Color getColor();
{
return COLOR;
}
public final int getNumCylinders()
{
return numCylinders;
}
}
So really need to "apply" these specs to the new carObject without modifying existing fields such as manufactureDate. The problem is how to minimize the code of changes to those 100+ child classes (preferably leave them untouched) while being able to update the carObject during runtime.
N.B. I was given to work on this code so I didn't write it in this condition to begin with.
Based on the description and example, you are using inheritance inappropriately. It looks like you are creating many classes where you should be using a single class and many object instances. If this is true, you also don't need a design pattern to solve the problem. Without further clarification of the problem, this should suffice:
class Car
{
private int manufactureYear;
private Color color;
private int numCylinders;
public int getManufactureYear() { return manufactureYear; }
public void setManufactureYear(int manufactureYear) { this.manufactureYear = manufactureYear; }
public Color getColor() { return color; }
public void setColor(Color color) { this.color = color; }
public int getNumCylinders() { return numCylinders; }
public void setNumCylinders(int numCylinders) { this.numCylinders = numCylinders; }
}
Example usages:
// make a blue 6-cylinder:
Car blue6 = new Car();
blue6.setColor(BLUE);
blue6.setCylinders(6);
// make a red 4-cylinder:
Car red4 = new Car();
red4.setColor(RED);
red4.setCylinders(4);
// Uh-oh, they painted my red car!
red4.setColor(YELLOW);
If you want to minimize changes, you could use my refactored Car class from above, and then clean up the child classes so they leverage it. Something like:
class CarOne extends Car { // extends my version of Car...
private static Color COLOR = Color.Red;
private static int CYLINDERS = 4;
public CarOne() {
setColor(COLOR);
setNumCylinders(CYLINDERS );
}
// getters deleted, base class has them now
}
Since there is in fact a base class, my guess is that 99% of the code does not reference the concrete car classes (only the base class), so you should be able to change things fairly easily. Of course, hard to say without seeing the real code.
It depends on how much control you have over the code that creates these objects. I'm going to assume that this design exists for a reason that was kind of lost in the car example, but if the objects are created by calling new, then there is little you can do other than change them, although you could use the rest of this answer to suggest a more flexible way to change them.
If you can control their creation, then a factory that uses composition and returns a different kind of car object that overrides the specific parameters you care about and calls the original for the rest would allow you to affect your changes on a specific instance without changing all of the original classes. Something like:
Car carOne = CarFactory.makeCar("CarOne", 2009);
Then inside that makeCar method, you can decide whether or not to return a CarOne object, or a composite implementation:
public class CompositeCar extends Car {
private Car original;
private Color myColor;
public CompositeCar(Car original, Color myColor) {
this.original = original;
this.myColor = myColor;
}
public int getYear() { return original.getYear(); }
public Color getColor() { return myColor; }
}
I'd also recommend taking a look at the Builder Pattern if you have cases (or entire groups of classes) which have complicated construction logic, especially if some fields are required in some Cars, and different sets of fields are required in others.
Your subclasses do not provide different behavior only different data.
Hence you should not use different subclasses only different arguments.
I would suggest add a "getCar" method to your base case and use it as an a factory method.
Add the Color and Cylinder properties and load them from ... anywhere it suits your needs, it may be a database, a properties file, a mock object, from the internet, from a cosmic place ... etc.
Before:
Car car = new CarOne(2009); // Using new to get different data....
carObject.getColor();
carObject.getNumCylinders();
After:
class Car {
// Attributes added and marked as final.
private final Color color;
private final int numberCylinders;
// original
private final int manufacteredYear;
public static Car getCar( String spec, int year ) {
return new Car( year,
getColorFor( spec ) ,
getCylindersFor(spec) );
}
// Make this private so only the static method do create cars.
private Car( int year, Color color, int cylinders ) {
this.manufacturedYear = year;
this.color = color;
this.numberCylinders = cylinders;
}
// Utility methods to get values for the car spec.
private static final getColorFor( String spec ) {
// fill either from db, xml, textfile, propertie, resource bundle, or hardcode here!!!
return ....
}
private static final getCylindersFor( String spec ) {
// fill either from db, xml, textfile, propertie, resource bundle, or hardcode here!!!
return ....
}
// gettes remain the same, only they are not abstract anymore.
public Color getColor(){ return this.color; }
public int getNumCylinders(){ return this.numberCylinders; }
}
So instead of create a new car directly you would get it from the getCar method:
Car car = Car.getCar("CarOne", 2009 );
....
I wouldn't recommend you to make your car "mutable" for it may bring subtle undesired side effects ( that's why I mark the attributes as final ) . So if you need to "modify" you car, you better assign new attributes:
Car myCar = Car.getCar("XYZ", 2009 );
.... do something with car
myCar = Car.getCar("Modified", 2009 );
//-- engine and color are "modified"
Additionally you may even map the whole car so you only use one instance.
By doing this you don't have to add setters to your code. The only thing you have to do would be search and replace
Car xyz = new WhatEver( number );
For
Car xyz = Car.getCar("WhatEver", number );
And the rest of the code should run without changes.
Related
If I have a non-static inner class, I know that it cannot contain static methods, because it requires an instance of the enclosing class in order to be accessible. However, is there any way to create a method that can be referenced with an instance of the outer class but not the inner one? Something along the lines of:
public class Family {
public final Set<Dog> pets = new HashSet<Dog>();
public class Dog {
public Color color;
public int weight;
public int height;
public Dog(Color color, int weight, int height) {
this.color = color;
this.weight = weight;
this.height = height;
Family.this.pets.add(this);
}
public void addDefaultBlack() {
new Dog(Color.BLACK, 10, 10);
}
public void addDefaultWhite() {
new Dog(Color.WHITE, 5, 5);
}
}
}
In such a way that I can reference it something like:
Family family = new Family();
family.Dog.addDefaultBlack();
...by requiring an instance of the outer class, but not the inner one. In a case such as this, Dog is not a static inner class because each dog must belong to a family, but I want some methods that could create dogs with some default properties and add it to the Family object of the enclosing class. The only way I could think to do this currently is to create an enum (such as something like DefaultDogs) and pass it as an argument in a new constructor, then switch-case it to apply the properties. That seems somewhat messy, so I'd prefer to avoid it. Is there a way to do this with methods as I've shown? What's the correct syntax? Sorry if I'm missing something obvious here.
EDIT: I'm aware I could put a method in the outer class, but for readability and logic it makes more sense to me to keep it in the inner class in my opinion. Is that the only way to make this work?
The following will do what you want. But you will need to pass an instance of the Family class to the method to be used to create a new instance of the Dog class. The addDefault classes can be declared static so they can be indirectly accessed vi Family.Dog.
import java.awt.Color;
import java.util.HashSet;
import java.util.Set;
public class FamilyDemo {
public static void main(String[] args) {
Family family1 = new Family();
Family family2 = new Family();
family1.new Dog(Color.orange, 70,40);
family2.new Dog(Color.green, 100,200);
Family.Dog.addDefaultBlack(family1);
Family.Dog.addDefaultWhite(family2);
System.out.println(family1.pets);
System.out.println(family2.pets);
}
}
class Family {
public final Set<Dog> pets = new HashSet<>();
public class Dog {
public Color color;
public int weight;
public int height;
public Dog(Color color, int weight, int height) {
this.color = color;
this.weight = weight;
this.height = height;
pets.add(this);
}
public static void addDefaultBlack(Family instance) {
instance.new Dog(Color.BLACK, 10, 10);
}
public static void addDefaultWhite(Family instance) {
instance.new Dog(Color.WHITE, 5, 5);
}
public String toString() {
return color + ", " + weight + ", " + height;
}
}
}
I thought about this some more and have a few ideas for you to consider.
Unless you are planning on drawing the pets, don't use Color. It is not use friendly for descriptive purposes. Create an enum for the Color and require it be used as an argument in the constructors. You can always add more colors and not affect someones existing implementation.
Change Dog class to Pet class. Then you can have an enum of possible pets. You can even have the enum types provide ranges for the pets to enforce invariants in the values. For example, if you allow a tarantula as a pet you wouldn't want to allow it to be 100 lbs. (yikes!). More pets can be added by simply adjusting the enum. Min and max values and others can all be specified as arguments to the enum types.
Finally, not only Families can have pets, but single people and even organizations. The root of your initial problem was having the inner class add an instance of dog to the enclosing class's Dog set. Why not just have a Pet class external to Family, useful by others. You could make it a PetFactory with a custom setting as well as standard default pets. Then leave it up to the using class to add the pet to the set.
The addDefaultBlack method would have to be an instance method of the outer class, you'd call family.addDefaultBlackDog(). Probably not what you were looking for.
So in a challenge in class, we had to use a public abstract Class Cycle as the parent class and create subclasses off of it. I used Unicycle Class as an example.
My professor refuses to let me put Color color as protected. He wants it private. He said the way that I can get the privacy issue worked out was by implementing the getter and setter for color. Initially they were set as abstract Color getColor() and abstract void setColor(Color color) but I tried implementing them inside the abstract class by making them public and giving them the method body.
The test in the code is:
cycle.setColor(Color.RED);
assertEquals(Color.RED, cycle.getColor());
I continue to get the error message,
The field Cycle.color is not visible
I know it works with protected but I have to use private.
Anyone have any hints they can throw at me here? I am going nuts with all of my research and failed trials.
public abstract class Cycle
{
//Declare instance variables
private String make;
private Color color;
//Create a constructor that only contains an argument for make
public Cycle(String make)
{
this.make = make;
}
//Create a constructor that contains an argument for make and color
public Cycle(String make, Color color)
{
this.make = make;
this.color = color;
}
//Create getter and setter methods
abstract int getNumberOfWheels();
//*********Was abstract Color getColor();
public Color getColor()
{
return color;
}
//*********Was abstract void setColor(Color color);
public void setColor(Color color)
{
this.color = color;
}
final String getMake()
{
//return the make of the object
return make;
}
Unicycle Class
public class Unicycle extends Cycle
{
//Create a constructor that only holds the argument make
public Unicycle(String make)
{
//Call on the super (parent) class to create the object with arguments
super(make);
}
public Unicycle(String make, Color color)
{
super(make, color);
}
//Create a method to get the number of wheels and return 1 since a unicycle only has 1 wheel
public int getNumberOfWheels()
{
return 1;
}
}
color is not visible to sub-classes since color is private in Cycle, so having a getter/setter in the Unicycle class results in a compilation issue.
Cycle already defines a getter/setter for color, and Unicycle is-a Cyle, so there's no need to attempt to override the getter/setter in sub-classes.
Remember that any public (or protected) method defined in a base class is available to sub-classes. This is one of the benefits of using inheritance.
My professor refuses to let me put Color color as protected. He wants
it private. He said the way that I can get the privacy issue worked
out was by implementing the getter and setter for color.
In case you were wondering if he is being difficult, I can tell you that he is trying to teach you a very important concept of Object-Oriented Programming. And that is limiting the scope of your variables in this case. You don't EVER want to give direct access to the data members of a class unless they are CONSTANTS. There are a few reasons for it, one of which is in case you need to add preliminary steps in the future before returning the value (i.e. return a value from an alternate source).
Now, you have something like this:
public abstract class Parent {
private String something;
protected Parent() {
something = "N/A";
}
protected String getSomething () {
return something;
}
protected void setSomething (String something) {
this.something = something;
}
}
public class Child extends Parent {
// bad use of override
#Override
public void setSomething (String something) {
super.setSomething(something);
}
// bad use of override
#Override
public String getSomething() {
return something;
}
public static void main (String[] args) {
Child child = new Child();
child.setSomething("New value");
System.out.println(child.getSomething());
}
}
public class Unrelated {
public static void main (String[] args) {
Parent child = new Child();
child.setSomething("Foo");
System.out.println(child.getSomething());
}
}
This works.... The field in the abstract class is private. Therefore, it is blocked from direct manipulation. The child classes can override a protected method of the abstract (parent) class and make it public for unrelated classes to call freely. I included a main method in both the child class and the unrelated class to illustrate this point.
The reason why the override is bad is because it doesn't do anything... HOWEVER, protected methods are restricted to be called outside the package or by classes unrelated to the class declaring the protected method. Therefore, if the unrelated class was outside of the package, it would not be able to call these protected methods. THEREFORE, you must override them by the child classes and make them public. THAT SAID, if this is the case, you could argue that the best thing is to make the protected method public in the parent class and avoid forcing implementing classes to override protected methods just for this reason.
I am currently in the process of refactoring the code I wrote for a text/console version of the Mastermind board game. I am a bit stuck with how to best approach improving this section my GameLogic class.
public GameLogic(GameSettings gameSettings)
{
// ..other stuff..
// initialise static members
Board.setTotalRows(gameSettings.getNumOfGuesses());
Board.setTotalColums(gameSettings.getCodeLength());
// InputBoard and OutputBoard extends the abstract class Board
inputBoard = new InputBoard();
outputBoard = new OutputBoard();
}
What I am trying to do is set the static values of totalRows and totalColumns in the Board class BEFORE constructing the inputBoard and outputBoard objects. The reason why I want to do this is because I need to have these values present when constructing instances extending Board (an abstract class). The reason why I am making these values static is because they should be the same across all instances extending from Board and so that I can do something like Board.getTotalColumns() throughout the application.
The reason why I think this is suspiciously bad is because it would be possible to declare inputBoard or outputBoard without first setting the static member variables and of course it would also be possible to accidentally set the values of the static member later on to any arbitrary value.
Another approach I thought of was to make the getters in GameSettings public and static so that I could do something like this instead:
public abstract class Board
{
private static final int totalColumns = GameSettings.getCodeLength();
private static final int totalRows = GameSettings.getNumOfGuesses();
// other stuff...
}
This would allow me to avoid using setters and the problems associated with using them as listed above. But wouldn't this defeat the purpose of instantiating a GameSettings object?
What do you think are better alternatives to approach this?
I am not an expert on design pattern. I would try something like below -
Board.java
abstract class Board {
private final GameSettings gameSettings;
Board(GameSettings gameSettings) {
this.gameSettings = gameSettings;
}
public int getTotalColumns() {
return gameSettings.getCodeLength();
}
public int getTotalRows() {
return gameSettings.getNumOfGuesses();
}
//Other abstract methods
}
InputBoards .java
class InputBoards extends Board {
InputBoards(GameSettings gameSettings) {
super(gameSettings);
}
}
OutputBoards .java
class OutputBoards extends Board {
OutputBoards(GameSettings gameSettings) {
super(gameSettings);
}
}
GameSettings .java
class GameSettings {
public int getCodeLength() {
//return your value;
}
public int getNumOfGuesses() {
//return your value;
}
}
Now I would do -
public GameLogic(GameSettings gameSettings) {
inputBoard = new InputBoard(gameSettings);
outputBoard = new OutputBoard(gameSettings);
}
First I will just put my sample code.
public class Shape {
public String colour;
public Shape(String colour) {
this.colour = colour;
}
}
public class Car {
public String colour;
public Car (String colour) {
this.colour = colour;
}
}
public class Colour {
public static String getColour(Object item) {
return item.**colour**;
}
}
I've read other questions related to this, but I just can't seem to understand. I found their original code was just too complex for me to get around. So I tried to make as simple a code as possible. Anyway, I want getColour to accept both the Shape and Car object. If I use Object like I did in my example, the "colour" in bold is considered an error. The error I get is "colour cannot be resolved or is not a field". What's wrong?
Also, I've heard a lot of "static methods are bad" etc., is this a case of it being bad? Because I find if I don't make it static, then I need to duplicate getColour methods in both the Shape and Car classes. If I should avoid static methods, then please suggest another way to do this.
What you're looking for is the concept of interfaces:
public interface Colourable {
String getColour();
void setColour(String colour);
}
You should modify the Shape and Car classes:
public class Shape implements Colourable {
public Shape(String colour) {
this.colour = colour;
}
private String colour;
public String getColour() {
return colour;
}
public void setColour(String colour) {
this.colour = colour;
}
}
(note that I've made the colour field private; this is common practice and called encapsulation)
You can then define your static method as
public static String getColour(Colourable item) {
return item.getColour();
}
And static methods are definitely not bad, though in this case the method itself is a bit superfluous, because if you already have an Colourable, you know you can call .getColour() to get its color. A bit more useful would be the method
public static boolean isRed(Colourable item) {
return "red".equals(item.getColour());
}
You can "unify" Shape and Car. There are two general approaches:
Inheritance and
Interfaces
Let's look at both.
Inheritance: When a class Porsche inherits (or, in Java syntax, extends) a class Car, you establish an "is-a" relationship. In this case: Porsche is-a Car. Now, the magic comes to work, when you use object references. You can now write something like this:
Car c = new Porsche();
Since a Porsche has everything, a Car has (plus some things on top), you can see a Porsche as a Car (each Porsche is a Car, but not each Car is a Porsche). Reading my last sentence carefully, it is obvious, that the following does not work and, in fact, produces a compile error:
Porsche p = new Car();
What you can now do is write a method, that expects a Car and pass in a Porsche (since every Porsche is a Car).
Coming back to your example. To get this working, you could define a common parent class for Shape and Car, let's call it Colourable and give it a method public Colour getColour(). Then, you could simply change your getColour(Object item) method to getColour(Colourable c).
Remeber the thing I said about the "is-a" relation? Ask yourself: is each Shape a Colourable? Is each Car a Colourable? Why should Car and Shape both be in the same bucket (Colourable)? And what to do, if Car already has a parent class, e.g. Vehicle? This solution is sub-optimal.
Interfaces: This is, where interfaces come into play. Interfaces guarantee, that certain methods are present. Instead of defining a common parent class Colourable, you could simply write Colourable as an interface, containing the method public Colour getColour(). Now Shape and Car can implements this interface. This forces you to implement this method in both classes. The beauty: you can use interfaces just like classes. Meaning your implementation of getColour(Colourable c) does not need to change.
For more details, please read the provided tutorials on Inheritance and Interfaces.
Seems like your trying to use duck typing, which isn't how Java works.
The easiest thing to do, IMHO, would be to define an interface to handle the color. E.g.:
public interface Colourful {
public String getColour();
}
public class Shape implements Colorful {
private String colour;
public Shape(String colour) {
this.colour = colour;
}
#Override
public String getColour() {
return colour;
}
}
public class Car {
private String colour;
public Car (String colour) {
this.colour = colour;
}
#Override
public String getColour() {
return colour;
}
}
Alternatively, if you don't want to change Shape and Car, you could use reflection to extract the colour field, but this is usually considered a bad idea, and you'd probably be better off not using it:
public static String getColour(Object o) {
Field colourField;
try {
colourField = o.getClass().getField("colour");
} catch (NoSuchFieldException e) {
// No such field
return null;
}
Object colourValue;
try {
colourValue = colourField.get(o);
} catch (IllegalAccessException e) {
// The field isn't public
return null;
}
if (!(colourValue instanceof String)) {
// The field isn't a String
return null;
}
return (String) colourValue;
}
The reason an error is thrown is that Object doesn't have a colour field. I wouldn't recommend it, but if you want to move forward with this design, you could make a class called ShapeCarParent (used in this case because I see no clear relationship between the two) and have both the classes inherit from that, and then change getColour, like so:
public class ShapeCarParent{
public String colour;
}
public class Car extends ShapeCarParent
public class Shape extends ShapeCarParent
public class Colour {
public static String getColour(ShapeCarParent item) {
return item.colour;
}
}
This is still pretty poor style, so you can also use an interface which you then implement in each class.
public interface ColorProperties{
public String getColour();
}
public class Car implements ColorProperites{
public String getColour() {
return colour;
}
}
public class Shape implements ColorProperites{
public String getColour() {
return colour;
}
}
Hope this helps.
I am experience some problems in understanding how the OO pattern works, My lecturer gave me the following question but I cannot solve it after thinking whole day
Scenario for my problems.
There is a class named "ShapeManager" which manages the Shape object. A class named "Shape" has two subclasses named "Circle" and "Rectangle"
The implementation of Shape class as follow
abstract public class Shape {
private String id;
private double length;
public Shape() {
}
public Shape(String id , double length) {
this.id = id;
this.length = length;
}
public void setID(String id) {
this.id = id;
}
public String getID() {
return id;
}
public void setLength(double length) {
this.length = length;
}
public double getLength() {
return length;
}
public abstract String getDetails();
}
The subclass Square as follow
public class Square extends Shape{
public Square() {
super();
}
public Square(String id , double side) {
super(id, side);
}
#Override
public String getDetails() {
return "Square => Id : "+getID() +", Side : "+ getLength() + ",Area : "+(getLength() * getLength());
}
}
The subclass Circle as follow
public class Circle extends Shape{
public Circle(){
super();
}
public Circle (String id, double radius) {
super(id, radius);
}
#Override
public String details() {
return "Circle => Id : "+getID() + ", Radius : "+ getLength() + ",Area: "+(3.14*(getLength() * getLength()));
}
}
The ShapeManager class as follow, this is not a completed class
public class ShapeManager {
public Shape createShape() {
}
public void updateLength(String id ){
}
public void deleteShape(String id) {
}
public void listShapes() {
}
}
ShapeManager have an association with Shape
ShapeManager --1------0..*--> Shape
The design of this package (All the classes above) can not be changed, implementation must be following OCP (Open-Closed Principle).
My question is: How am I suppose to complete createShape method? Without parameter, it is seemingly impossible to create an object either a Rectangle or Circle.
ShapeManager cannot create a shape if not knowing what this shape is (Square, Circle or something else). And it really doesn't know because you say the method createShare has no parameters. Either you misunderstood the question or the lecturer didn't explain it well. You should ask him/her for clarifications. If you look at the libraries of Java or any other OO language, I am pretty sure you won't find such scenario and implementation pattern as the one you gave in your example.
#croraf
You should find some other reading I think e.g. the classic book http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612. The main idea of a factory is that it returns something whose type the caller doesn't know, and doesn't care about. For example, if you have a method createSocket() in some SocketFactory, this method is usually defined to return an interface or an abstract class Socket. But actually it returns new SocketImpl1() and new SocketImpl2() which are concrete classes. What the factory returns may depend on many things - a system property, the underlying OS, anything you can think of. The main idea is that the factory centralizes the creation of Socket objects at one single place. This way, if you need to make a change, you can make it just in the factory. I think this book also has some decent Java counterparts too, you may look around. Other free good sources are referenced here.
Real world examples of Factory Method pattern
I think you should have something like this, similar to how BorderFactory from java API works.
public class ShapeManager {
public Shape createCircle() {
...
return Circle;
}
public Shape createSquare() {
....
return Square;
}
...
public void updateLength(String id ){
}
public void deleteShape(String id) {
}
public void listShapes() {
}
}
You can't create shape without knowing type which shape would You like to create. You can define enumeration for types and pass the type value to the createShape(). And there You can switch between types and create the concrette shape You want.
For me, Its classic Factory pattern.
public class ShapeFactory {
public abstract Shape getShape(int shapeId);
}
public interface Const {
public static final int SHAPE_CIRCLE =1;
public static final int SHAPE_SQUARE =2;
}
public class SimpleShapeFactory extends ShapeFactory throws BadShapeException {
public Shape getShape(int shapeTypeId){
Shape shape = null;
if(shapeTypeId == Const.SHAPE_CIRCLE) {
//in future can reuse or cache objects.
shape = new Circle();
}
else if(shapeTypeId == Const.SHAPE_SQUARE) {
//in future can reuse or cache objects
shape = new Square();
}
else throw new BadShapeException("ShapeTypeId="+ shapeTypeId);
return shape;
}
}
Calling:
ShapeFactory factory = new SimpleShapeFactory();
//returns a Shape but whether it is a Circle or a
//Square is not known to the caller.
Shape s = factory.getShape(1);
s.getDetails(); // circle details called
//returns a Shape but whether it is a Circle or a
//Square is not known to the caller.
s = factory.getShape(2);
s.getDetails(); //Square details called
References:
The Open Close Principle states that the design and writing of the code should be done in a way that new functionality should be added with minimum changes in the existing code. The design should be done in a way to allow the adding of new functionality as new classes, keeping as much as possible existing code unchanged.