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.
Related
I am working with a legacy scala codebase, and as is always the case modifying the code is quite difficult without touching different parts.
One of my new requirement in to make several decisions based on some input parameters. Problem is that these decisions are to be made at various points along the execution. So either I encapsulate all those parameters in a case class instance and pass it along. But it means I would have to modify multiple methods signatures, and I want to avoid this approach as much as possible.
Another approach can be to create a global object containing all those input parameters and accessible from different points in the execution. Is it a good approach in Scala?
No, using global mutable variables to pass “hidden” parameters is not a good idea, not in Scala and not in any other programming language. It makes the code hard to understand and modify, because a function's behaviour will now depend on which functions were invoked earlier. And it's extremely fragile, because you might forget setting one of those global parameters before invoking the function, which means that it will use whatever value was stored there before. This is the kind of thing that can appear to work for years, and then break when you modify a completely unrelated part of the program.
I can't stress this enough: do not use global mutable variables, period. The solution is to man up and change those method signatures. Depending on the details, dependency injection may or may not help in your particular case.
In the MATLAB OOP framework, it can be useful to cast an object to a struct, i.e., define a function that takes an object and returns a struct with equivalent fields.
What is the appropriate place to do this? I can think of several options:
Build a separate converter object that takes care of conversions between various classes
Add a function struct to the class that does the conversion to struct, and make the constructor accept structs
Neither option seems to be very elegant: the first means that logic about the class itself is moved to another class. On the other hand, in the second case, it provokes users to use the struct function for any object, which will in general give a warning (structOnObject).
Are there altenatives?
Personally I'd go with the second option, and not worry about provoking users to call struct on other classes; you can only worry about your own code, not that of a third-party, even if the third party is MathWorks. In any case, if they do start to call struct on an arbitrary class, it's only a warning; nothing actually dangerous is likely to happen, it's just not a good practice.
But if you're concerned about that, you can always call your converter method toStruct rather than struct. Or perhaps the best (although slightly more complex) way might be to overload cast for your class, accepting and handling the option 'struct', and passing any other option through to builtin('cast',....
PS The title of your question refers to typecasting, but what your after here is casting. In MATLAB, typecasting is a different operation, involving taking the exact bits of one type and reinterpreting them as bits of another type (possibly an array of the output type). See doc cast and doc typecast for more information on the distinction.
The second option sounds much better to me.
A quick and dirty way to get rid of the warning would be disabling it by calling
warning('off', 'MATLAB:structOnObject')
at the start of your program.
The solutions provided in Sam Roberts' answer are however much cleaner. I personally would go for the toStruct() method.
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.
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.
I have class method that returns a list of employees that I can iterate through. What's the best way to return the list? Typically I just return an ArrayList. However, as I understand, interfaces are better suited for this type of action. Which would be the best interface to use? Also, why is it better to return an interface, rather than the implementation (say ArrayList object)? It just seems like a lot more work to me.
Personally, I would use a List<Employee> for creating the list on the backend, and then use IList when you return. When you use interfaces, it gives you the flexability to change the implementation without having to alter who's using your code. If you wanted to stick with an ArrayList, that'd be a non-generic IList.
# Jason
You may as well return IList<> because an array actually implements this interface.
The best way to do something like this would be to return, as you say, a List, preferably using generics, so it would be List<Employee>.
Returning a List rather than an ArrayList means that if later you decide to use, say, a LinkedList, you don't have to change any of the code other than where you create the object to begin with (i.e, the call to "new ArrayList())".
If all you are doing is iterating through the list, you can define a method that returns the list as IEnumerable (for .NET).
By returning the interface that provides just the functionality you need, if some new collection type comes along in the future that is better/faster/a better match for your application, as long as it still implements IEnumerable you can completely rewrite your method, using the new type inside it, without changing any of the code that calls it.
Is there any reason the collection needs to be ordered? Why not simply return an IEnumerable<Employee>? This gives the bare minimum that is required - if you later wanted some other form of storage, like a Bag or Set or Tree or whatnot, your contract would remain intact.
I disagree with the premise that it's better to return an interface. My reason is that you want to maximize the usefulness a given block of code exposes.
With that in mind, an interface works for accepting an item as an argument. If a function parameter calls for an array or an ArrayList, that's the only thing you can pass to it. If a function parameter calls for an IEnumerable it will accept either, as well as a number of other objects. It's more useful
The return value, however, works opposite. When you return an IEnumerable, the only thing you can do is enumerate it. If you have a List handy and return that then code that calls your function can also easily do a number of other things, like get a count.
I stand united with those advising you to get away from the ArrayList, though. Generics are so much better.
An interface is a contract between the implementation and the user of the implementation.
By using an interface, you allow the implementation to change as much as it wants as long as it maintains the contract for the users.
It also allows multiple implementations to use the same interface so that users can reuse code that interacts with the interface.
You don't say what language you're talking about, but in something .NETish, then it's no more work to return an IList than a List or even an ArrayList, though the mere mention of that obsolete class makes me think you're not talking about .NET.
An interface is essentially a contract that a class has certain methods or attributes; programming to an interface rather then a direct implementation allows for more dynamic and manageable code, as you can completely swap out implementations as long as the "contract" is still held.
In the case you describe, passing an interface does not give you a particular advantage, if it were me, I would pass the ArrayList with the generic type, or pass the Array itself: list.toArray()
Actually you shouldn't return a List if thats a framework, at least not without thinking it, the recommended class to use is a Collection. The List class has some performance improvements at the cost of server extendability issues. It's in fact an FXCop rule.
You have the reasoning for that in this article
Return type for your method should be IList<Employee>.
That means that the caller of your method can use anything that IList offers but cannot use things specific to ArrayList. Then if you feel at some point that LinkedList or YourCustomSuperDuperList offers better performance or other advantages you can safely use it within your method and not screw callers of it.
That's roughly interfaces 101. ;-)