A correct hierarchy for a Shape model - oop

If I had to create a OOP model for a geometric Shape hierarchy which would be the best considering also a Point class?
Thanks.

What about using java.awt.Shape ?

If you want to completely encapsulate the idea of a shape, it should not be a hierarchy, as there are an infinite number of shapes in the universe. Instead, it should just be one Shape class. It should consist of a series of lines and curves. Then, you can have methods to check if it conforms to particular shape definitions, e.g. IsCircle(), IsSquare() etc...
You could also have methods and/or constructors that set it to a particular type of shape.

All shapes can probably implement an IShape interface. IShape would require an Area() method, and a IsIntersectingWith(IShape otherShape) method. This simplistic view though raises some other questions about how you will implement dynamic dispatch (triangle/triangle intersection requires a different algorithm from triangle/segment).
This of course is assuming you actually need this functionality. Assuming a graphics oriented shape library, you can define transformations like Rotate, Translate, Scale. You could also enforce the use of Union, Intersect or whatever other set operation (but those two can express everything you might need).
You can also base things towards computational geometry and provide method functions that convert any IShape into a Polygon.
My point is, the functionality that can be enforced through an IShape should follow the expected use. If you don't have any expected use (since its educational to start with) you should make the use as part of the exercise itself, or as a discovery field (how about this use, or that use, can we express all this functionality in one interface or should we split it into many)

Related

inheritance vs composition - specific case

I have been reading about inheritance vs composition. I know there is already allot about this topic on this site, but i have a question about this specific example I hope will not be seen as duplicate.
Some guidelines I have gathered so far:
Prefer composition over inheritance.
Has-a relationship will therefore almost always mean composition.
Is-a relationship CAN mean inheritance is best, but not always.
So now for the example
I have been working on a simple game engine to practice C++. For this I have made some classes:
The Image class that contains an image that can be rendered.
The Transform class is all about positioning.
The Sprite class contains an image that can be rendered, in a specific position.
There is more of course, but let’s keep it simple for the example.
So - Sprite HAS an image and HAS a position (transform). Following the guideline that would mean composition for both. BUT I think it is just so much easier to have Sprite inherit from Transform.
Because I what to do things sprite->setPosition() and sprite ->setScale().
If a Sprite inherits from Transform, I don’t have to do anything, sprite->setPosition() automatically calls Transform::setPosition() for the sprite object.
If Sprite HAS a Transform, I would have to redirect ALL of these kind of methods to the Transform! (It's how I have been doing it so far and it seems to work fine)
I don’t want to write things like this for every positioning method: (there are quite a few already)
Sprite::setPosition(Vector2 position) {
mTransform.setPosition(Vector2 position);
}
But It seems to go against convention.
What do you all think?
When you say "easier" I think you mean "faster", because let's face it, forwarding the calls from the Sprite to the Transform component it's not difficult at all, it just takes more typing (and "less typing" is good, but I would weigh other things first). The problems of choosing inheritance over composition could not be there now, but could arise later.
With public inheritance you just have to declare the inheritance, and all the public interface from Transform is available in Sprite. All. If one day you add a "Rotate" method to the Transform, but don't want Sprites to be shown upside down, then you have to hide the base class method somehow. There are good answers here from Matthieu and CodeFirst about how to do that hiding in C++. But as Matthieu points there, by hiding the method you violate the Liskov Substitution Principle. If you had used composition, you could have just ignored that "Rotate" method in the public interface for Sprite.
With private inheritance you would be a little bit better, because it represents a "is implemented in terms of" relationship between Sprite and Transform, closer to reality than the "is a" relationship represented by public inheritance. But then you would need to put "using" statements to make available the methods from Transform in Sprite (see Eugen answer also in the previous link). So you end up still having to write extra code to achieve your purpose (although less than with composition).
With composition I feel that you have easier options to deal with design problems. Do you want to simply call the component method? You forward the call. Do you want to ban the component method? You don't add it to the Sprite interface. Do you want to add functionality to one method (e.g. keeping the Transform scale from being set to such value that the size of the Sprite Image is too small)? You add the method to the interface but do some extra processing/checkings before/after calling the Transform component...
If you can get your hands on Scott Meyers' Effective C++ book, you have two items that are worth reading for this discussion: "Use private inheritance judiciously" and "Model 'has-a' or 'is-implemented-in-terms-of' through composition". A final point extracted from there in favor of composition: "Both composition and private inheritance mean is-implemented-in-terms-of, but composition is easier to understand, so you should use it whenever you can"

Method implementation enforcement in functional programming vs OOP

I'm starting to learn F# with the wonderful site https://fsharpforfunandprofit.com
While reading about pattern matching in the entry about four key concepts that differentiate F# from a standard imperative language, I found this sentence (emphasis mine):
These kinds of choice types can be simulated somewhat in C# by using
subclasses or interfaces, but there is no built in support in the C#
type system for this kind of exhaustive matching with error checking.
That seems strange to me, because I think we can obtain an exactly equivalent result with a method definition in an interface (or with an abstract method in an abstract class) in C#: it enforces all the inheriting classes to implement that method, in the same way that in the F# code it enforces the draw method to provide an implementation for all the "inheriting" types.
The difference is that in the functional case all the implementations are in the same method, while in the object oriented case, each implementation is encapsulated in its class... but conceptually you get the same enforcement in both cases, so I don't see any benefit in the functional approach.
Am I missing something? Can somebody clarify this for me?
The key insight is that there are two ways of modeling domain (broadly speaking).
Let's take classes and interfaces. Say you declare IShape and make Circle, Rectangle, and all others implement it. Great. What methods are you going to have on IShape? Let's say Draw. So far so good.
Now imagine you implement yourself a dozen shapes. And then, a few months later, you find yourself in need of another operation. Let's call it IsEmpty. What do you do? You add IsEmpty to IShape, and then you go into each of the dozen classes and add IsEmpty to them. A bit of a hassle, but ok, you can do it.
A few months down the road you want to add another operation. Then another. And another. You get tired of this pretty quickly, but that's still fine, you grit your teeth, but you do it.
But then there's the next problem: somebody else who is using your library wants to add an operation of their own. What do they do? They can't modify the IShape interface, it's in your library. They can ask you to do it and republish the library (not very efficient, is it?). Or they can implement the operation in terms of if + is - i.e. if (shape is Circle) { ... } else if (shape is Rectangle) { ... }, and so on. But then they hit the very difficulty described in the article you linked - the compiler won't protect them from missing a shape!
On the other hand, take discriminated unions. You describe the union, and then add operations all you want, left and right. Every operation handles all cases within itself (and the compiler verifies that all cases are indeed handled), and you can even add new operations in other projects that reference your library without modifying the original code. Total nirvana!
But then, a few months down the road, you find out that you need another case - say Triangle. You can, of course, add this case to the type, but then you'd have to go and add handling for it in every single operation. Even worse: those people who are using your library - their code will break when they get the latest version, and they will have to modify their additional operations as well. Tedious!
So it seems that there are two different mutually exclusive ways:
Either you make it easy to add new cases, but hard to add new operations (aka "open world" model).
Or you make it easy to add new operations, but hard to add new cases (aka "closed world" model).
This is a well known problem in language design. So well known it has its own name - the "Expression Problem". There are actually languages that let you have your cake and eat it, too - Haskell has type classes, Clojure has protocols, Rust has traits, etc. Neither of the solutions that I've seen are elegant enough in practice, to the point of getting one to wonder whether solving the expression problem is even worth it.
F# does not solve this problem[1] - you can't have both ways at the same time. However, F# at least supports both ways separately: classes+interfaces for "open world", discriminated unions for "closed world". C#, on the other hand, supports only "open world".
More importantly, it turns out that in real programs "closed world" modeling is far more useful than "open world". Programs modeled this way turn out to be far more understandable, less buggy, more concise. "Open world" models usually come in useful when you expect your program to be extended after it's written, by somebody you don't necessarily know - aka "plugins". This situation does happen, but not that often.
[1] if you don't count shenannigans with statically resolved type parameters, which don't reliably work in all circumstances anyway
So, conceptually, we are talking about two quite different approaches for modelling a domain.
Consider the functional approach that we see described in the article:
type Shape = // define a "union" of alternative structures
| Circle of radius:int
| Rectangle of height:int * width:int
| Point of x:int * y:int
| Polygon of pointList:(int * int) list
let draw shape = // define a function "draw" with a shape param
match shape with
| Circle radius ->
printfn "The circle has a radius of %d" radius
| Rectangle (height,width) ->
printfn "The rectangle is %d high by %d wide" height width
| Polygon points ->
printfn "The polygon is made of these points %A" points
| _ -> printfn "I don't recognize this shape"
The key point here is that Shape defines that there are four possible options: Circle, Rectangle, Polygon and Point.
I cannot invent a new union case somewhere else in my program, Shape is strictly defined to be one of these options and, when pattern matching, the compiler can check I haven't missed one.
If I use a C# style model:
interface IShape {}
class Circle : IShape {}
class Rectangle : IShape {}
class Point : IShape {}
class Polygon : IShape {}
The possible types are unbounded. In one or more other files, I can simply define some more if I feel like it:
class Triangle : IShape {}
class Pentagon : IShape {}
class Hexagon : IShape {}
You can never know how many IShapes there might be in existence.
This is not true of the F# Shape we defined above. It has four options and only four.
The discriminated union model is actually very very powerful because often, when we're modelling a domain in software, the possible states in that domain are actually a relatively small and succinct set of options.
Let's take another example from the F# for Fun and Profit site of a Shopping cart:
type ShoppingCart =
| EmptyCart
| ActiveCart of unpaidItems : string list
| PaidCart of paidItems : string list * payment: float
If I model my cart in this way, I'm vastly reducing the scope for possible invalid states because my cart can be in one of these three states and no others.
Interfaces and classes will let you model exactly the same states but they will not prevent you from also creating an arbitrary number of additional states that are completely meaningless and irrelevant to your domain.

Should I make one abstract class with many derived classes or just one general class?

C++ Should I make one abstract class with many derived classes or just one general class?
Classic example is the abstract Shape object with derived classes Square and Triangle that hold specific geometry and functions.
Why don't I just make one general class called Shape that includes a more general geometry data member to hold a dynamic amount of points that could either be a square or a triangle?
Functions could take some parameter indicating what type of shape it was e.g. Shape.process("square"); instead of something like Square.process();
Is my question clear? Is this purely a stylistic choice?
You should avoid creating "god" classes that do a bunch of stuff. What if you will have to implement a lot of shapes? A class should have only one responsibility, should be open for extension and closed for modifications. Check the class design principles or the SOLID principles of design. You should avoid complicated design and big classes that have multiple responsibilities just because at a moment it will become a pain to maintain them or add extra functionality. Unit testing will also be something more easy to do with a good design.
You cannot get an answer to this type of question in general. It is going to depend on the situation and requirements for whatever problem you are attempting to solve. In some cases, it will make sense to have an interface with derived classes. In others, it will make sense to have a generalized class. Without knowing the requirements for the problem, you will get no real answer.
It really depends on what you need the Shape for. For example if you are just drawing it, then yeah a general Shape class that just draws line from point to point would be perfect (for polygons anyway). But what if you wanted to calculate the area. It would probably be easier to have a Square and Triangle class where the getArea() function uses the appropriate area formula. There is no hard and fast rule it simply depends on what you need them for

How should I model pathfinding in the object oriented paradigm

My goal is to implement a (very simple) strategy game.
For the moment, I'll start with the map and two characters (I want the terrain to affect them differently) to experiment with pathfinding
The problem is that I have very little or no experience in object oriented design. I've used C++ classes before, but it was pretty straightforward: for instance, a class Graph implemented using an array of sets, with a method AStar. I didn't have in mind the concept of "several players".
I've thought of the following elements/classes: Game, Map and Character. Eventually a Pathfinder class.
First question: the position of a character is something the game should know? The map? or each character?
( I think the game should )
Second question: where would it be a good choice for a "findPath" method?
The Game?
Should a pathfinding algorithm be a method of Map? Something like map.findPath(character, srcpos, dstpos)
In the Character class? It makes more sense to do character1.findPath(map, srcpos, dstpos)
If I added a Pathfinder class, it would have to build its own representation of the map in order to determine the shortest path. And before doing that, it would have "to ask" the map how the terrain affects each player.
( I prefer the latter )
It seems the construction of an auxiliary structure (and asking the map) to apply, let's say, A* is something that I can't avoid.
Making things object-oriented is not a goal, it's a tool to be used when it makes sense. C++ is a language with lots of functionality that you can easily drown yourself with, so my advice is to keep things simple and easy.
This can mean keeping data and logic tightly together sometimes, or separating it completely other times.
First question: My initial reaction is that the character should know its position. But how you represent it with data depends on how you intend to use it, so both the game, the character and potentially also the map needs to know where the character is.
Second question: It depends on what the Map class is. Is it an object representing the map itself with necessary functionality exposed to the rest of your program, or is it a toolbox of functions that works on a simple data representation of the map?
If the Map class represents the map, it should have the necessary functionality exposed for a Pathfinder class to work on it (the pathfinding algorithm will need to have some additional data derived from the map, maybe temporary, maybe persistent).
If the Map class does not represent the map, you can put the pathfinding functionality in it. I think it would belong there in that case. If the pathfinding code causes the Map class to get too big, you should separate it into its own class anyway.
First Question: The position of the character should be a part of character itself (makes sense this way) for me.
Second Question: Finding a path logically cannot be a part of Map. Then you would be violating one of OOP principles i.e. Single Responsibility.
According to me you should create the PathFinder class. You can design it in this way
class PathFinder{
PathFinderAlgorithm algorithm;
//other required values according to your design
Path findPath(){
algorithm.apply();
}
//other required methods according to your design
}
PathFinderAlgorithm is an interface.
Using this you can also change the algorithm that you are using to find the path. Like if you in future need to find the longest path, all you have to do is create another class which will find the longest path and replace it in the PathFinder class.

"Visitor" a lot of different type of object

in one application I have a lot of dirrerent object, let´s say : square, circle, etc ... a lot of different shape ---> I´m sorry for the trivial example.
With all this object I want to create a doc of different type : xml, txt, html, etc.. (e.g.: I want to scan all the object (shapes) tree and produce the xml file.
The natural approach I thought is visitor pattern, I tried and it works :-)
- all the objects have one visit method accepting the IVisitor interface.
- I have one concrete visitor for every kind of do I want to create : (XmlVisitor, TxtVisitor, etc). Every visitor has one method "visit" for every kind of object.
My doubt is ... it doesn´t seems scaling well if I have a lot of object ...
from the logic point of view it´s ok, i have just to add the new shape and the method in the concrete Visitor, that´s all.
What do you think ? is an althernative possible ?
I think that you have correctly implemented a visitor pattern and as a result you also have implemented a double dispatching mechanism. If you consider the "not scaling well" as a need to add a bunch of methods in case of adding a new shape and/or visitor, then it is just a side effect of the pattern. Some people consider this "method explosion" as harmful and opt for a different implementation, such as having a "decision matrix" object. For this example in particular I think that the DD approach is the way to go and that actually it does scale well, since you add new methods as you add new requirements (i.e. you add new visit* methods as new shapes are added or you add a new visitor class as new document types are needed).
HTH
It seems to me that what worries you the most is that you are matching against many different kinds of objects, and worry that as more and more object types are added, the performance will suffer. I don't think you need to worry about that, though: The performance of the visitor pattern is not really affected by the potential number of objects or visitors, since it is based on virtual table lookup - the passed object will contain a link to (a link to) the method which should be called.
So the visitor pattern, though relatively expensive in indirect accesses, is scalable in this regard.
I believe you have :
A class hierarchy (Shapes in your example) and
Operations on the class hierarchy (exportXML, exportToHTML etc in your example)
You have to consider what is more likely to change -
You should choose Visitor pattern if the class hierarchy is more or less fixed but you would like to add more operations in future. Visitor pattern will allow you to add more operations (e.g. JSON export) without touching the existing class hierarchy.
OTOH if the operations are more or less fixed, but more Shape objects can be added, then you should use regular inheritance. Define a ShapeExport interface which has methods like exportToXML, exportToHTML etc. Let all Shapes implement that interface. Now you can add new Shape which implements the same interface without touching existing code.