Let's say I have a class modeling some kind of object, for example a graph (in the graph theory sense).
I will have the graph structure and data inside the class, but what about other more complex behaviors? For example, I want to create a function that transforms the graph in a specific way, or that dumps the graph in JSON format. Should these functions be inside or outside the class?
My first thought is to put these kinds of functions inside the class, but if I put a lot of functions, each graph object will take way more memory right?
Are there clear guidelines for this question ? Also, is it language dependant?
There are not strong guidelines around this AFAIK, apart from OOP principles.
The function that dumps the graph in JSON format should be part of the class, because it directly uses the graph data-structure (which should be private), so instead of exposing that externally and using a different class to convert the graph to JSON, it's more convenient to have a method like graph.toJson() and get JSON string.
On the same idea, if you want to transform a graph into a tree, or to balance a tree, it's more convenient to call graph.toTree() or tree.balance(), so methods should be part of the class.
Generically, I would add the functionality outside of the class, only when it can be re-used and it doesn't depend on the internal state of the class.
When you add multiple methods on a class, this doesn't mean the object consumes more memory. Memory gets allocated when the method is called. When you just pass around graph objects, the main memory will be allocated by the graph data-structure.
Related
Is there a guideline or recommendation about how to pass object to functions? Is it recommended to always pass the full object to a function:
calculateSomething(car1, car2, aircraft)
Or is it better to only pass the properties that are really needed to the function?
calculateSomething(car1.speed, car1.length, car2.speed, aircraft.height)
The first approach seems to be more convenient, especially when the function requires many more properties. However, my intuition tells me that the second approach is more computationally efficient as the function does not has to handle the full objects.
Is there a general programming advice for this or is it for every function a trade-off between readability and speed?
Never pass the properties directly. Because that breaks the principles of Object orientated programming, (Encapsulation) specially if it will involve making changes to the properties.
Always use getters and setters to make changes to the object properties.
I have to implement an algorithm which fits perfectly to the procedural design approach. It has no relations with some data structure, it just takes couple of objects, bunch of control parameters and performs complicated operations on them, including creating and modifying intermediate temporal data, subroutines calls, many cpu-intensive data transformations. The algorithm is too specific to include in either parameter object as method.
What is idiomatic way to wrap such algorithms in an OOP language? Define static object with static method that performs calculation? Define class that takes all algorithm parameters as constructor arguments and have result method to return result? Any other way?
If you need more specifics, I'm writing in scala. But any general OOP approach is also applicable.
A static method (or a method on a singleton object in the case of Scala -- which I'm just gonna call a static method because that's the most common terminology) can work perfectly fine and is probably the most common approach to this.
There's some reasons to use other approaches, but they aren't strictly necessary and I'd avoid them unless you actually need an advantage that they give. The reason for this is because static methods are the simplest (if least versatile) approach.
Using a non-static method can be useful because you can then utilize design patterns like the factory pattern. For example, you might have an Operator class with a method evaluate. Now you could have different factories create different Operators so that you can swap your algorithm on the fly. Perhaps a calculator might have an AddOperatorFactory, MultiplyOperatorFactory and so on. Obviously this requires that you are able to instantiate an object that represents the algorithm. Of course, you could just pass a function around directly, as Scala and many other languages allow. Classes allow for inheritance, though, which opens the doors for some design patterns and, well, you're asking about OOP, not Scala specifically.
Also useful is the ability to have state with an object. With static methods, your only options for retaining state are either having global state (ew) or making the user of the static methods keep track of this state (more work for the users). With an instance of an object, you can keep that state inside the instance. For example, if your algorithm is a graph search, perhaps you'd want to allow resuming a search after you find the first match (which obviously requires storing state).
It's not much harder to have to do new MyAlgorithm().doStuff() instead of MyAlgorithm.doStuff(), so if in doubt, I would err on the side of avoiding static methods if you think you'll need the functionality that having an instance offers.
I am teaching myself how to use object oriented programming with MATLAB and have a question about access.
I have three current classes that need to interact with each other. One class, which I'll call main, is what the user will interface with (or the gui if I build one). Main stores all of the pertinent data that the use may want and has a few methods to perform some preprocessing and to construct the main object. Main also calls the constructors for the two other classes.
Another class, I'll call it instruction, loads information about the steps to process the data (this is a recursive process) and some other information.
The final class, which I'll call core, performs the core operations of the process.
Heres what my question is. Within main I have some "helper" methods that are used in the preprocessing. I want the access to these helper methods to be private so that the user cannot see or use them. Some of these helper functions also need to be used by the processes in core. My question is how do I grant access to the helper functions in main so that only main and core can access them? I have tried to understand the information provided here: http://www.mathworks.com/help/matlab/matlab_oop/selective-access-to-class-methods.html, but when I try something like:
classdef main < handle
%this is the main class
properties
core %the core object
instruction %the instruction object
end %properties
methods (Access = {?core,?main})
... %some code
end %methods
end %class
Matlab gives me this error:
Illegal value for attribute 'Access'.
Parameter must be a string.
Any help would be greatly appreciated!
Andrew
Btw, I realize that having three different classes is unnecessary here but as I stated I am just learning object oriented programming and when I started this project I thought it would be a good idea to have multiple classes because the total project will be over 5000 lines of code.
Is it possible you're using a relatively old version of MATLAB?
The ability to give access to class methods to specific classes was implemented in release 2012a.
If you're using a version of MATLAB older than that, you can only set method access attributes to public, protected or private.
Note that the documentation page you link to always refers to the current version of MATLAB (2014a at the moment). You can access old versions of the documentation via the website as well by logging into your MathWorks account.
If you have methods of main that need to be accessed by core, that could be a sign that you've designed your class relationships poorly. If core is a property of main, then perhaps it could be a method of core, and main could call it via core.
Selective access is needed quite rarely. The main reason for not using it, is that it breaks the encapsulation principle of OOP. I would consider changing your design, before implementing it.
For more information, check out the friend keyword in C++. Most likely you will find a lot of information on it, and why not to use it.
If I have a function (say messUp that does not need to access any private variables of a class (say room), should I write the function inside the class like room.messUp() or outside of it like messUp(room)? It seems the second version reads better to me.
There's a tradeoff involved here. Using a member function lets you:
Override the implementation in derived classes, so that messing up a kitchen could involve trashing the cupboards even if no cupboards are available in a generic room.
Decide that you need to access private variables later on, without having to refactor all the code that uses the function.
Make the function part of an interface, so that a piece of code may require that its argument be mess-up-able.
Using an external function lets you:
Make that function generic, so that you may apply it to rooms, warehouses and oil rigs equally (if they provide the member functions required for messing up).
Keep the class signature small, so that creating mock versions for unit testing (or different implementations) becomes easier.
Change the class implementation without having to examine the code for that function.
There's no real way to have your cake and eat it too, so you have to make choices. A common OO decision is to make everything a method (unless clearly idiotic) and sacrifice the three latter points, but that doesn't mean you should do it in all situations.
Any behaviour of a class of objects should be written as an instance method.
So room.messUp() is the OO way to do this.
Whether messUp has to access any private members of the class or not, is irrelevant, the fact that it's a behaviour of the room, suggests that it's an instance method, as would be cleanUp or paint, etc...
Ignoring which language, I think my first question is if messUp is related to any other functions. If you have a group of related functions, I would tend to stick them in a class.
If they don't access any class variables then you can make them static. This way, they can be called without needing to create an instance of the class.
Beyond that, I would look to the language. In some languages, every function must be a method of some class.
In the end, I don't think it makes a big difference. OOP is simply a way to help organize your application's data and logic. If you embrace it, then you would choose room.messUp() over messUp(room).
i base myself on "C++ Coding Standards: 101 Rules, Guidelines, And Best Practices" by Sutter and Alexandrescu, and also Bob Martin's SOLID. I agree with them on this point of course ;-).
If the message/function doesnt interract so much with your class, you should make it a standard ordinary function taking your class object as argument.
You should not polute your class with behaviours that are not intimately related to it.
This is to repect the Single Responsibility Principle: Your class should remain simple, aiming at the most precise goal.
However, if you think your message/function is intimately related to your object guts, then you should include it as a member function of your class.
D2.0 classes have a __monitor class property that "gives access to the class object's monitor" (documentation). I searched around a bit and did not find any information except for this bit of detail. So: what is a monitor? Why is one monitor used for all synchronized member functions? Is it a synchronization primitive used for synchronizing member functions similar to Java? And why is the __monitor property in the language def if you are not supposed to use it / what are the use-cases?
The monitor is a lazily initialized object that all synchronized methods synchronize on, just like in Java. Unlike Java, D is a systems programming language and exposes lower level details of how things work just in case you need to hack them, even if doing so is usually a bad idea. This allows you to customize behavior. For example, it is possible to customize the monitor object of a class, or to use a core.sync.mutex that shares a monitor with the class that owns it.