Which is better of the two
Creating properties and passing it within methods in class or passing objects as parameters to a method?
I have a datamodel object instance returned by a handler class, which i want to pass it to two different methods, so what is the best approach, assing it to a property in the class and then use it into these two methods, or pass the instance as a parameter to the method?
If an object is only needed temporarily by a class to extract data from for example, then pass it as an method argument.
You should take a step back from the code details and have a more abstract look: If the object has no direct purpose, or does not meaningfully belong with the class, then passing it as a method argument is fine. If the object could be seen as a part of the class (i.e. something the class needs all the time, or relies on a lot), then it might be an option to make it part of the class using a property.
Something else to consider is that setting a property, and then call a method that uses that property, separates the data from the operation. I mean, this obscures what the method does, and on what data it works. Of course this could be overcome by correct naming of those methods. Again look at things at a bit more abstract level to find the most meaningful way (i.e. what is closest to the purpose of the class and what the methods are actually doing) of structuring things.
In other cases these object may belong to underlying/other classes, which means that your current class is only passing them on. In those cases it's clear that you should literally pass them on with methods.
Related
I'm currently learning Kotlin through the Kotlin Android Developer program from Udacity. There's two sample apps using DiffUtil.ItemCallback, but declare it in different ways. Both sample apps use a ListAdapter, however one declares the DiffUtil like this: companion object DiffCallback : DiffUtil.ItemCallback<MarsProperty>()
while the other like this: class SleepNightDiffCallback: DiffUtil.ItemCallback<SleepNight>()
Both DiffUtils are passed as parameters to the ListAdapter, with the only difference being that in the case of the class implementation, it has to be initialised:
class PhotoGridAdapter : ListAdapter<MarsProperty, PhotoGridAdapter.ViewHolder>(DiffCallback)
class SleepNightAdapter : ListAdapter<SleepNight, SleepNightAdapter.ViewHolder>(SleepNightDiffCallback())
The only difference between those sample apps is that one downloads and shows images from the internet (the one with the PhotoGridAdapter), while the other shows data from a database, so
my question is: Is one implementation preferred compared to the other? Are there any performance differences between them?
This is probably a matter of opinion. Mine is that the callback should be an object, or anonymous object, but not a companion object.
All it's doing is comparing properties of two objects. It doesn't have to hold any state. So it makes sense for it to be a singleton object rather than a class that you have to instantiate. Whether you define it as a named singleton object or define in place as an anonymous object assigned to a property doesn't make much different in communicating intent.
But it doesn't make sense to me to make it a companion. It's already nested and has a name. All companion does is suggest that you should need to call its functions directly and that the name PhotoGridAdapter should also be thought of as a callback. For instance, it enables you to pass the name PhotoGridAdapter to some other adapter as its DiffUtil callback, which is nonsensical. The only reason it might possibly make sense is if you also want to use it as a utility for comparing items, so you could call functions like PhotoGridAdapter.areContentsTheSame directly. However, I don't think this is likely. Usually, the contents of the callback's functions are either very trivial like passing through equals() or they are very specific to the nature of updating the displayed list.
So I've had to subclass NSURLProtocol because I am using a UIWebView and want to intercept ajax calls which works fine as per this example. I have to get the data from the request from + (BOOL)canInitWithRequest:(NSURLRequest *)request which causes a problem, I now need to call instance methods to do things with the data, but I can't because it's a class method.
How could I call an instance method based on the contents of what is in the request?
You cannot call instance methods from a class method without having an instance first. This is true for all object-oriented systems, AFAIK. After all, the instance methods (usually) use data that the class method cannot have. Imagine an object with a property name, and you now have one thousand objects with different names. How should the class method know which name to use?
So you need to find a way to somehow query instances of your class based on your request, or find a way to get at the information in a way that does not involve instance variables (if a method doesn't use instance variable you can turn it into a class method or even C function). There are many different ways to solve the "query problem", which to chose is highly dependent on your design and even taste.
canInitWithRequest: shouldn't do any work whatsoever, it should just respond with "YES" or "NO". "startLoading" is where you do the work.
I often need to decide between these two strategies for the object design:
An object that is fully initialised and ready to use after its construction. The constructor often requires a complex list of parameters, hence the object initialisation is nontrivial. All objects having it as a member variable will also need nontrivial constructors. This may lead to code whose complexity is concentrated at object constructors, often making the code hard to follow.
An object with default constructor. The object variables are set individually by means of setter methods. This approach has the disadvantage that most methods need to check whether the object is fully initialized, hence complicating the code.
What is your personal preference between the two, and how do you decide when to use one or the other?
In my opinion if a constructor is getting too bloated it's time to split up your object in more different, smaller objects. This might be impossible in some rare cases, but in most cases it can be done.
Neither.
Huge parameter lists indicates the object does too much. Lots of properties that need to be set before the object can have a valid and useful output indicates it does too much.
So neither approach is a solution as far as I'm concerned.
There are lots of ways to break these things up, but outside of a specific scenario, the only rule is, "It needs doing".
Aggregation into other objects, "controller" classes, various communicator patterns. Are some categories first class objects, can some be hidden in the implementation.
I don't accept that the two options you present are the only ones, except possibly from a pragmatic point of view in terms of getting the code out of the door. Which one I was then forced to choose, would simply depend on how many calls to the constructor with different parameters the code required, versus how much validation would be needed to confirm all the properties were set, and possibly the impact on unit tests, which because the object is a mess would be unwieldy or limited.
If a constructor takes many arguments — you call this non-trivial object initialisation — and you don't want to split up your class into smaller ones, then one alternative is to put the parameters into a Parameter Object and then only pass that object to the constructor.
Second, I believe that you should distinguish between...
object properties that absolutely must be set if the object is supposed to do its work, and there is no sensible default value. These properties should be initialised via a constructor parameter.
object properties that can be set optionally, or overridden, by the user. While you might initialise such properties in the constructor, you don't have to have a separate constructor parameter for them. Instead, you might assign a sensible default value to them that still can be overridden by the user through a setter method.
There is also an alternative to the first type of properties (those that must absolutely have a user-provided value): properties which are provided through overriding an abstract getter in a derived class:
abstract class ComplicatedFoo {
protected abstract T getSomeDependency(); // replaces required ctor parameter
}
P.S.: The book "Dependency Injection" by Dhanji R. Prasanna (Manning Publications) gives a good overview of the various ways how to initialise an object.
It's always good to initialize all your variables in the constructor, but to a default value. If it is difficult to get the value of the variable (for example, you have to call some function somewhere to get that value), you may set that value to an invalid one and then later you set the correct value.
It is not a good idea to make the constructor so complex, because you can't return an error in the constructor (I don't know if it is ok to throw an exception in the constructor or not, because I particulary don't like trhowing exceptions anywhere). Also, you can't call virtual functions there, and so on.
An approach I like when the construction of the class is complex is to create an "init" function. Then I can do something like:
Person::Person()
{
age = -1;
...
}
int Person::Init()
{
age = functionThatReturnsTheAgeFromSomeDB();
if (age == -1 )
{
return DB_ERROR;
}
...
}
And so on.
I have a strong feeling that I do not know what pattern or particular language technique use in this situation.
So, the question itself is how to manage the growing parameter list in class hierarchy in language that has OOP support? I mean if for root class in the hierarchy you have, let's say 3 or 4 parameters, then in it's derived class you need to call base constructor and pass additional parameters for derived part of the object, and so forth... Parameter lists become enormous even if you have depth of inheritance more than two.
I`m pretty sure that many of SOwers faced this problem. And I am interested in ways how to solve it. Many thanks in advance.
Constructors with long parameter lists is an indication that your class is trying to do too much. One approach to resolving that problem is to break it apart, and use a "coordinator" class to manage the pieces. Subclasses that have constructor parameter lists that differ significantly from their superclass is another example of a class doing too much. If a subclass truly is-a superclass, then it shouldn't require significantly more data to do its job.
That said, there are occasional cases where a class needs to work on a large number of related objects. In this situation, I would create a new object to hold the related parameters.
Alternatives:
Use setter injection instead of constructor injection
Encapsulate the parameters in a separate container class, and pass that between constructors instead.
Don't use constructors to initialize the whole object at once. Only have it initialize those things which (1) are absolutely required for the existence of the object and (2) which must be done immediately at its creation. This will dramatically reduce the number of parameters you have to pass (likely to zero).
For a typical hierarchy like SalariedEmployee >> Employee >> Person you will have getters and setters to retrieve and change the various properties of the object.
Seeing the code would help me suggest a solution..
However long parameter lists are a code-smell, so I'd take a careful look at the design which requires this. The suggested refactorings to counter this are
Introduce Parameter Object
Preserve Whole Object
However if you find that you absolutely need this and a long inheritance chain, consider using a hash / property bag like object as the sole parameter
public MyClass(PropertyBag configSettings)
{
// each class extracts properties it needs and applies them
m_Setting1 = configSettings["Setting1"];
}
Possibilities:
Perhaps your class(es) are doing too much if they require so much state to be provided up-front? Aim to adhere to the Single Responsibility Principle.
Perhaps some of these parameters should logically exist in a value object of their own that is itself passed in as a parameter?
For classes whose construction really is complex, consider using the builder or factory pattern to instantiate these objects in a readable way - unlike method names, constructor parameters lack the ability to self document.
Another tip: Keep your class hierarchy shallow and prefer composition to inheritence. That way your constructor parameter list will remain short.
I'd like to know whether this approach is correct or if their are better ways of doing this.
I have what is basically a Person class which has a number of other classes as variables, each of the custom classes is instantiated by passing the Person ID and then that class retrieves the data it needs using that ID. I expose the variable classes via Properties.
Currently I am instancing the variable classes when I create an instance of the Person class, and the large number of these mean that the time it takes to instantiate the Person class is growing. My idea was to move the instancing of the variable classes to the Propertie declaration and then using an If statement here to instantiate it if it hasn't yet been done.
As I said above is this approach correct or is their a better way of doing this?
Thanks
There is a term for the technique you're describing; it's called "lazy-loaded properties". It should definitely help spread out your load on this object away from a "front-loaded" constructor.
On a different note, it sounds like what you're describing is going to result in a terribly tightly-coupled object model (if you don't have one already) which is likely to have a negative impact on this code's maintainability. However, I don't think that a serious dissertation on that topic and how to work otherwise is really within the scope of this question.
Just to clarify: If you mean instantiating the classes on the getter of their accessor then yes this is a fine approach - referred to as Lazy Loading.
Eg
public Property ChildClass as PersonChildClass
Get
if _childClass is Nothing
_childClass = new PersonChildClass(_personId)
End If
return _childClass
End Get
End Property