I'm thinking about the solution for my application. Here's the situation: I have a class with a method that takes ObjectA as an input parameter and calls several small methods. Each one of these methods needs some parts of the ObjectA (they don't overlap, i.e. method1() needs ObjectA.field1 and ObjectA.field2, method2() needs ObjectA.field3 and so on...)
Given the general good code practices and performance, is it better to pass ObjectA to each one of these methods so they can extract the value they need on their own or is it better just pass them values? I mean:
method1(ObjectA);
method2(ObjectA);
or
method1(Object1.getField1(), ObjectA.getField2());
method2(ObjectA.getField3());
Keep in mind, with your code, you're not actually passing ObjectA. Namely, you're passing the reference type to ObjectA, so on a performance note the difference between passing a String object reference and a ObjectA object reference would be negligible.
The way I would write it
I would pass the whole object, if the method is pertinent to the class. My reasoning for this is to split up class knowledge as much as possible. What I mean by this is the following.
public void doSomethingRelatedToTheClass(String param)
{
// Do something with param.
}
My first criticism here is that this method assumes that the input is the correct field. My second, is that now, the class calling this code needs to know a little bit more about this method, because it has to call it like this:
doSomethingRelatedToTheClass(myObject.getValue());
And what this means is, if you find that another member of ObjectA works better inside this method, or you want to access other members of ObjectA, and you change doSomething() to reflect this change, you also need to change the method call, to:
doSomethingRelatedToTheClass(myObject.getOtherValue(), myObject.getValue());
So by passing in the whole object, you abstract that detail away, and the method can handle it; namely:
doSomethingRelatedToTheClass(myObject); // Doesn't need to know what you do with it.
public void doSomethingRelatedToTheClass(ObjectA object)
{
String val = object.getValue();
String otherVal = object.getOtherValue();
}
When a change to one class, results in a change in other classes, this is an Anti-pattern called Shotgun Surgery.
Edit
I've had chance to review my answer here and I've amended my original answer slightly because I believe it isn't the best solution for all situations. As above, if a method is related to a class specifically, then the instantiation of that class (or more preferably, its superclass or implemented interface[s]) should be the parameter.
The time this is not the case is when the functionality can be generic. An example of a generic function might be:
public String[] findNouns(String sentence);
In this case, finding the nouns in a sentence might be appropriate for lots of use cases, and not just the use cases that you have defined. As such, passing in the value is the only sensible approach because otherwise, you couple two pieces of logic together that have no direct relationship. The finding of nouns and the arbitrary object you have defined.
In Summary
If the method is logic that is related to the object, pass in the object
If the method has nothing to do with the object, and the object is just using it as a utility function, then pass in the value and name the function generically.
Let's examine a scenario. Now this may or may not be your scenario but it illustrates a point.
Lets say field1 and field2 in your case are two integers and method1 sums them and returns the result.
If you pass in the objects then that method can only ever sum those two fields. The method is also now strongly coupled with those objects.
On the other hand, if you pass in only the fields, the two integers in this case your method becomes more generic. You can now sum any 2 arbitrary integers regardless of which objects they are on.
In general though, always expose as little of your objects to other methods and classes. This promotes loose coupling.
Exceptions
AS maaartinus points out if for example field1 and field2 were Points and method1 calculated the distance between those two points, then I would have to agree that passing two Points would be better than passing 2 xy integer pairs (4 parameters)
Hope this helps
I'd say, it depends. A method may be clearer and more general if it operates on the arguments rather than requiring a whole object. Sometimes you have the arguments ready (e.g., x and y) and would have to aggregate them first into e.g. a Point in order to be able to call the method. Sometimes you have a different unrelated object (e.g., some ImmutablePoint, obviously not extending java.awt.Point) and would have to extract the coordinates and create an object to pass.
Usually, if the passed object is the proper abstraction, then passing it as a whole is the way to go. It's not a performance question, it's about readability and maintainability. See also the Law of Demeter which may lead to looser dependency on the passed object.
As others have said, it depends but in my experience passing entire objects makes code harder to read and maintain.
Lets consider this method getUserDetails(User user) which relies on few methods like getUserAddress(User user) getUserFamilyInfo(User user) etc which may further connect to different data sources to fetch the information.
There is no easy way to know that getUserFamilyInfo needs only userId or it needs userId and lastName or something else from user when entire object is passed. It makes it hard to understand dependencies among different services and do any refactoring.
I prefer to pass individual arguments if count is less than 3 or create a dto if handful of properties are required from a vary large object.
Related
I have an ArrayList where I want to call two methods on the first two objects in the list, and different methods on the rest, how can I do this the easiest way?
So far I have this
ArrayList<Material> materials = new ArrayList();
StyklisteMetodeKlasse.fillArray(materials);
for(Material materialer: materials.subList(0, 1)){
int brugerInput = 0; // this is only a temporary varible
materialer.setAmount(Material.calculatePlanks(brugerInput, materialer.getLength()));
materialer.setAmount(Material.calculatePlanks(brugerInput, materialer.getLength()));
//here is some code where i call different methods on the rest of the materials
When I call a method on the "materialer" does it apply for all the objects or just the first, then the second?
The best approach would most likely be the simplest one. Using polymorphism, and try and get the type of the object at runtime and select what you need to do, would be a sleek solution, but as you said, it might get complicated, especially if you do not have control over the structure and nature of the objects being passed to you.
Alternatively, you could make your classes implement an interface which abstracts the operation that you would need to do. This would allow you to always call the same method, without having to worry about who is what.
As it has been pointed out in the comments, having hardcoded index values could potentially cause more trouble than it will ever solve, since it assumes that who ever is consuming your method has inside knowledge of it how specifically works, as opposed to what it should do.
Most likely, the best approach would be to change your method to take 2 lists, as opposed to 1. This approach is easier to understand and also gives you more control and has you make less assumptions, which is usually always a good thing.
Is there any difference between this declaration
Thread.State state = Thread.State.NEW;
and that
Enum<Thread.State> state = Thread.State.NEW;
in Java? Instead of the second option is a bit longer?
It's the same case as comparing between:
Child o = someChild;
and
Parent o = someChild;
Enum is the parent class of all enum types. Therefore, with the second line, the code cannot contain references to specific members of Thread.State, specifically the members described in this section of the language spec.
Is there any difference ....
In practice, in this particular case, probably no.
In theory, Thread.State is a subtype of Enum<Thread.State>. If Thread.State declared (non-private) fields or methods, then you could use them via the first declaration of state, but not the second one.
In general, the first form is preferable ... for that reason.
Also, I don't think you would be able to see an enum's static methods values() and valueOf via the variable declared in the second declaration; e.g.
state.valueOf("BLOCKED")
However, calling a static method via an instance reference is bad style.
Two practical differences (as opposed to language-lawyerly reasons) that come to mind:
If you declare state as an Enum<Thread.State>, then you won't be able to pass it to any methods that expect a Thread.State.
If you declare state as an Enum<Thread.State>, you'll leave the reader — whoever needs to touch this code in the future — wondering why you've written it that way.
Neither of these is a terribly deep reason; we could easily imagine a parallel universe where most people used Enum<Thread.State> instead of Thread.State, just as (in our universe) most people use List<...> instead of ArrayList<...> (when possible). But since most people don't do that in our universe, you're better off just following the common pattern, to minimize the risk of confusion and accidental incompatibility.
Incidentally, in case this is going to be your next question . . . the main situation where you would use Enum is when you want to write something generic that works for many different enum types. An example of this in the JDK is EnumMap<K extends Enum<K>,V>, which is a special map implementation that gets space and performance benefits out of knowing that its keys are enum values.
(And note, incidentally, that you can't write EnumMap<Enum<Thread.State>, String>, because Enum<Thread.State> doesn't extend Enum<Enum<Thread.State>>. Instead, you must write EnumMap<Thread.State, String>. So this is an example of difference #1 that I mentioned above: if you declare state as an Enum<Thread.State>, then you can't use it as a key in an enum-map.)
Assuming we have an object inside an object, inside another object, what is the best way to retrieve the value of a private variable outside the two objects?
The simplest way seems to be to do something like this:
object1.object2.object3.getvalue();
Is this acceptable? Or would it be better to call a method which calls a method, which calls a method?
The second option seems unnecessarily laborious, considering you would basically be having the same method created in 3 different classes.
use getter to get any object
ex: Object obj = object1.getObject2().getObject3();
It depends on your definition of "acceptable". It may be acceptable in your case. It is hard to tell without proper context.
However, there are something you may consider, level-by-level:
1. Use of getters
Although such kind of getters are still far from satisfactory, it is still better than using direct property access
i.e. Instead of accessing object1.object2 by direct field access, provide Object2 getObject2() in Object1, so that the code looks like:
object1.getObject2().getObject3().getValue()
2. Null handling
Usually when we chained such kind of property navigation, we will have problem that in some level, null is returned, which makes object1.getObject2().getObject3().getValue() throwing NPE.
If you are using Java 8, consider returning Optional<>. e.g. in Object1, getter of object2 should look like Optional<Object2> getObject2()
With such change, your code can be made null-safe by something like:
Value value = object1.getObject2()
.flatMap(Object2::getObject3)
.map(Object3::getValue)
.orElse(Value.emptyValue())
3. Law of Demeter
In order to make a more loosely-coupled design, you may want to provide access to that value in API of Object1, instead of exposing multiple levels of indirection. Hence:
Value value = object1.getFooValue();
(Keep using Optional<> if it fit your need)
for which internally it retrieve the value from Object3. (Of course, Object2 may also want to do something similar)
4. Getter is evil
Always remember you should try to avoid providing internal representation of your object. Your objects should provide meaningful behavior instead of simply act as a value object for you to get or set data. It is hard to give an example here but ask yourself, why do you need to get the value for? Is that action more appropriate to be provided by your object itself?
The best way is to not think of your objects as data stores. A class should be defined to have some work to do, some cluster of related responsibilities. In order to perform that work to fulfill those responsibilities some internal data may be kept, and some nested objects contained. Serving out data should not be the goal of your objects, generally speaking.
Encapsulation
The whole idea of encapsulation in object-oriented programming is to not expose that internal data and nested objects. Instead publish the various available chores by declaring methods on your higher/outer object. Encapsulation frees you to change those internals without breaking the outside calling code – avoiding fragility is the goal.
For example, an Invoice object can contain a collection of LineItem objects. In turn each LineItem object contains other objects for product, quantity, price, extended cost, taxability, tax rate, tax amount, and line cost. If you want to know the total amount of sales tax added across the items, instead of asking the Invoice for the LineItem, and then asking the LineItem for TaxAmount object, define this chore as a method on Invoice, getTotalTaxAmount. Let that method figure out (and keep to itself!) how to go through the contained objects to collect the relevant information.
If you absolutely must expose that nested data, again define a method at the highest level that returns a copy of the desired data or a collection of the desired objects (probably copies of those objects). Again, the goal is to avoid exposing the objects within objects within objects.
Then, within that highest method, as the correct Answer by Raaga stated, define a getter that calls a getter.
Getter Methods versus Direct Member Access
In a very simple structure of data you could access the objects directly. But generally better to use getter methods. Again the reason is encapsulation. Having a getter method allows you the flexibility of redefining the implementation details of the stored data.
For example, presently you could store the "Sex" variable as a String with values of "F" or "M". But later you may decide to take advantage of Java's nifty enum feature. So you replace those single-character "F" & "M" strings with enum instances Sex.FEMALE and Sex.MALE. Having a getter provides a level of insulation, so the Strings can be replaced internally with enums. The getter method continues to return a String (and internally translating the enum to an "F" or "M" String to be returned). This way you can work on restructuring your class without breaking those dependent outside objects.
object1.object2.object3.getvalue();
This chaining seems incorrect...Object chaining under such scenario is always object1.someMethod().someOtherMethod(). Or something like suggested above in an answer using getter object1.getObject2().getObject3().
I hope it helps.
What you described may be the simplest way (if object2 and object3 are accessible) but it is definitely not the way to go. As Raaga pointed out getters are a lot better to retrieve members of a class and these members should then be private or protected to prevent errors.
If you can do
object1.object2.object3.getvalue();
you can also do something like
object1.object2 = null;
which is most likely not what you want to allow. This is one of the basic concepts of object oriented programming. Classes should handle their implementation details / secrets and not directly offer them to the outside! This is what getters/setters are for.
This way you have more control over the access and what can be done and what can't. If you should only be able to retrieve object2 from object1 but not be able to change it, you can only offer a getter and no setter.
If you should also be able to change it, it is also better to use setter for more control, because you can do checking in your setter to prevent my example where I put a null pointer as your object2
And just in case you worry about efficiency that calling a method might not be as efficient as directly accessing a member, you can rely on Java to internally optimize your method call that it is not any slower than the direct access.
first of all I'm using java, even though it could be a question for any language
say I have a complicated system, now sometimes I end up building objects (setting all the parameters), then passing it over to a "target layer"(manager), which opens the object (getting the parameters).
if I were to pass all the parameters in one function, it would be considered poor design, because there's suppose to be a small amount of parameters per function
this seems like a waste, and in the past I also decided to set the parameters straight to the "target layer"
is there a design pattern that deals with this issue?
or something that books or experts in the subject recommend?
You might take a look on the Effective Java Book that will cover Design method signatures carefully
There will be three techniques for shortening long parameters :
break the method into multiple methods, each which require only a subset of the parameters
create helper classes to hold group of parameters (typically static member classes)
adapt the Builder
pattern from object construction to method invocation
Since you're asking the reference, I hope it can help solve your problem and don't forget to buy the book here
Since you were asking about book references, here is one from Clean Code, Chapter 3: Functions:
When a function seems to need more than two or three arguments, it is
likely that some of those arguments ought to be wrapped into a class
of their own. [...]
Reducing the number of arguments by creating objects out of them may
seem like cheating, but it’s not. When groups of variables are passed
together, [...] they are likely part
of a concept that deserves a name of its own.
So I guess it's ok to group a lot of method arguments into classes, as long as these classes represent some coherent concepts.
Personally if I do something like this, I like the wrapper class to be immutable and created by a dedicated builder. Which increases the number of additional classes twofold (wrapper and the builder), but enables the treatment of such a class as one atomic argument.
Extract the parameters into its own "Parameter-Object" (pattern name) and pass that object to the function.
If the Parameter-Object itself is complicated to construct, use the Builder-Pattern which simplifies the construction if the object can be constructed in different ways.
For Example:
function(param1, param2, param3, ...)
The parameters are then extracted into an Object:
class ParamObject {
param1;
param2;
param3;
}
with its corresponding setters and getters.
To construct the ParamObject use the BuilderPattern.
And finally, the invocation would look like this:
function(paramobject):
Inside the function the former arguments are then retreived from the object.
As siledh stated: Make sure to group arguments into classes that share a common concept, which means that it´s ok to create several classes out of the paramlist.
This sounds like a Data Transfer Object to me.
http://martinfowler.com/eaaCatalog/dataTransferObject.html
Lets say I have a method:
someMethod(X anObject)
Where X is a type of object that is extremely complex. By this I mean it is not something one can easily instantiate on the fly. I need to somehow unit test someMethod, but I cannot so simply create an X object to put in as parameters.
So I first think to try and mock the object, but the problem I run in to is the someMethod function calls many methods of anObject, meaning this X object that is being mocked has a latge amount of functions that need to be called, and thus need to be mock-expected. To make things worse, these X object methods being called return more X objects, meaning I have to mock objects, to expect mock method calls, to return more mock objects.
Regarding this scenario I have a few questions, as I'm new to the concept of unit testing:
The lengthy unit test method aside, I find my unit test to not only be testing as to whether a method works or not, but also specifying the implementation (because I'm basically specifying most of the code that is being called in the method itself with the mock-expects). Is this a problem (mostly to the concept of unit testing itself)?
Is there any way to get around this, even if only to make my unit test methods be a lot less verbose and more maintainable?
I thought about taking a serialized X object from somewhere else, saving that, and then whenever I call my unit test method, I would unserialize my X object and run that as parameters. This is just some random idea I thought of the top of my head; does anyone actually do this?
In case anyone is wondering what exactly I'm doing, I'm using the IDebugContextListener interface to grab debugging information regarding data on a stackframe at a given step on the java debugger. The "X" that I am referring to are objects that are defined by the interface here, including objects such as IValue, IVariable, and IStackframe. All these variables are provided to me by the Java debugger during runtime.
The fact that you have this difficulty is a symptom of a design problem. When something is hard to test, refactor until it isn't hard to test.
If one object needs to call too many methods of another, then encapsulation is poor, and responsibilities are poorly placed. Presumably, the Single Responsibility Principle is not being followed. If code calls methods that return objects, and must call methods on those in turn, then the Law of Demeter is not being followed.
Your pain comes from the fact, that your method does not comply with the Single Responsibility Principle. Your method does a lot of things with X -- and X also sounds a too comlex. This makes testing very hard -- even with mocking.
Break your method down into manageble chunks, that only do one thing each.