Suppose to have a polygon class like this one:
public class Polygon
{
Point[] _vertices;
public class Polygon(Point[] vertices)
{
_vertices = vertices;
}
}
To make triangles, squares, hexagons would you rather:
CreateSquare
static method that returns a ready to use Polygon class?This:
public class Square : Polygon
{
public class Polygon(double size)
{
_vertices = new Point[]{ new Point(0,0), new Point(size,0), new Point(size,size), new Point(0,size)};
}
}
or this:
public class Polygon
{
Point[] _vertices;
public class Polygon(Point[] vertices)
{
_vertices = vertices;
}
public static Polygon CreateSquare(double size)
{
double verts = new Point[]{ new Point(0,0), new Point(size,0), new Point(size,size), new Point(0,size)};
return new Polygon(verts);
}
}
What approach is more correct from the OOP programming point of view? Please note that there derived classes don't add anything to original Polygon one.
In addition, in the latter case, is there any convenient naming convention?
Is there any additional approach I don't know about?
Thanks.
Open-closed Principle (OCP) states: Objects or entities should be open for extension but closed for modification. This means that a class should be extendable without modifying the class itself. Consider a scenario where the user would like the sum of additional shapes like triangles, pentagons, hexagons, etc.
SOLID is an acronym for five main principles of Object-Oriented Programming (OOP): single responsibility principle, open-closed principle, Liskov substitution principle, interface segregation principle and dependency inversion principle.
In object-oriented programming, the open–closed principle states "software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification"; that is, such an entity can allow its behaviour to be extended without modifying its source code.
In a nutshell, the developer must need to change only a specific part of the code (a class or a function) every time a requirement changes. Using a statically typed language like Java, C#, etc. the open/closed principle is generally achieved by using inheritance and polymorphism.
There's never a definite answer for this question without knowing the context in which these classes are being used, however if there's no need for more specific classes I wouldn't create them. You wouldn't create a RedPolygon
or BlueSquare
either, should you add a Color
property to Polygon
.
As soon as there is behavior exclusive to squares you could create the child class - I could for instance imagine that some mathematical operations like a hit test would perform faster on squares than on polygons-that-happen-to-be-squares.
To adhear to the SOLID principles. I would go with the solution using inheritance.
The Open/Closed principle states entities should be open for extension, but closed for modification. So to get another shape you shouldn't need to touch the Polygon class.
If someone wants to add a Hexagon he would simply create a new source file with the Hexagon inherit from Polygon instead of modifying your existing Polygon source which would require him to have access to your source. Also modifying existing source code would add the risk of introducing bugs with your new code. While for your simple example the risk wouldn't be that big for just creating new shapes, the risk would rise as soon as you want to add some calculations specific to the different shapes.
You could argue with the YAGNI principle which states you should not implement some feature if there is no need to. So if you don't need to account for further extension cause you got full control over your source and all the programms that use this source you could also go with the other solution using static "factory" methods.
For a more in depth discussion you could refer to this article
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With