In code I found:
String age = null;
String place = null;
new Employee(firstParam, secondParam, null, null, age, place);
Class Employee is not our class, probably generated from wsdl file where parameters(age and place) are called alter, platz so someone tried to name null parameters to know which is which but is it good practice? Another problem is that age and place are translated while other two parameters are just null but beside of that is creating variable with null value just to pass it in next line to constructor is okey?
In my experience, when I have pregenerated class defs that expose contracts that don't suit my needs, I tend to abstract them behind a factory method (may not be a full fledged builder, but depends..) and expose overloaded contracts that help API users to simply pass whatever args are actually needed. Now as to whether naming variables as null is considered good practice or not, i think that is more subjective of your choice rather than an established pattern. But IMO, simply passing null would be cleaner than writing few extra lines only to pass method args.
There is no clear yes or no on this pattern. It is indeed commonly used in some areas.
It has the obvious advantage that it introduces the naming and by that making your code easier to read and maintain, which is always good and also reduces likelyness of bugs.
But it also has disadvantages. The biggest is probably that, for a reader, the intend of the variable may not be directly clear. Tripping into thinking that it might be used later on, thus polluting your variable scope. It might also just not be very convenient if you employ this pattern all the time.
Without going into much detail, there are some other solutions to it:
Most IDEs have a feature called parameter-hints
Some languages, like Kotlin have named-parameters
A builder pattern for the method-call would introduce explicit naming
Redesign the method to not allow optional null-parameters (some consider optional-parameters a bad practice)
Get rid of optional parameters by overloading your method
Apart from that, the question is probably too opinion-based for StackOverflow, especially since there is not really a strong opinion on this pattern in the community.
No, it is not a good practice to do something like this. Anyway, when you're declaring some fields like this String age; , age will be null by default. Instead I would suggest to look over some generic builder patterns (look at #SpaceTrucker 's answer please) instead of instantiating by constructors with more than 2 parameters.
Related
there are two questions with microstream database and its class StorageConfiguration:
1) What ist the difference of the methods New() and Builder() and the DEFAULT construct?
2) Why the methods are writting uppercased? That does not seem to be Java naming convention.
Thanks for any answers!
I am the MicroStream lead developer and I can gladly answer those questions.
To 1)
"New" is a "static factory method" for the type itself.
"Builder" is a static factory method for a "builder" instance of the type.
Both terms can be perfectly googled for more information about them.
A quick service as a starting point:
"static factory method":
https://www.baeldung.com/java-constructors-vs-static-factory-methods
"builder pattern":
https://en.wikipedia.org/wiki/Builder_pattern
--
To your actually second question, about the "DEFAULT" construct:
If I may, there is no "DEFAULT" construct, but "Default".
(Conventions are important ... mostly. See below.)
"Default" is simply the default implementation (= class) of the interface StorageConfiguration.
Building a software architecture directly in classes quickly turns out to be too rigid and thus bad design. Referencing and instantiating classes directly creates a lot of hardcoded dependencies to one single implementation that can't be changed or made more flexible later on. Inheritance is actually only very rarely flexible enough to be a solution for arising architecture flexibility problems. Interfaces, on the other hand, only define a type and the actual class implementing it hardly matters and can even be easily interchangeable. For example, by only designing via interfaces, every instance can easily be "wrapped" by any desired logic via using the decorator pattern. E.g. adding a logging aspect to a type.
There is a good article with an anecdote about James Gosling (the inventor of Java) named "Why extends is evil" that describes this:
https://www.javaworld.com/article/2073649/why-extends-is-evil.html
So:
"Default" is just the default class implementing the interface it is nested in. It makes sense to name such a class "Default", doesn't it? There can be other classes next to it, like "Wrapper" or "LazyInitializing" or "Dummy" or "Randomizing" or whatever.
This design pattern is used in the entire code of MicroStream, giving it an incredibly flexible and powerful architecture. For example:
With a single line of code, every part of MicroStream (every single "gear" in the machine) can be replaced by a custom implementation. One that does things differently (maybe better?) or fixes a bug without even needing a new MicroStream version. Or one that adds logging or customized exception handling or that introduces object communication where there normally is none. Maybe directly with the application logic (but at your own risk!). Anything is possible, at least inside the boundaries of the interfaces.
Thinking in interfaces might be confusing in the beginning (which is why a lot of developers "burn mark" interfaces with a counterproductive "I" prefix. It hurts me every time I see that), but THEY are the actual design types in Java. Classes are only their implementation vehicles and next to irrelevant on the design level.
--
To 2)
I think a more fitting term for "static factory method" is "pseudo constructor". It is a method that acts as a public API constructor for that type, but it isn't an actual constructor. Following the argumentation about the design advantages of such constructor-encapsulating static methods, the question about the best, consistent naming pattern arose to me. The JDK gives some horribly bad examples that should not be copied. Like "of" or "get". Those names hardly carry the meaning of the method's purpose.
It should be as short but still as descriptive as possible. "create" or "build" would be okay, but are they really the best option? "new" would be best, but ironically, that is a keyword associated with the constructors that should be hidden from public API. "neW" or "nEw" would look extremely ugly and would be cumbersome to type. But what about "New"? Yes, it's not strictly Java naming conventions. But there already is one type of methods that does is an exception to the general naming rule. Which one? Constructors! It's not "new person(...") but "new Person(...)". A method beginning with a capital letter. Since the beginning of Java. So if the static method should take the place of a constructor, wouldn't it be quite logical and a very good signal to apply that same exception ... or ... "extension" of the naming convention to that, too? So ... "New" it is. Perfectly short, perfectly clear. Also not longer and VERY similar to the original constructors. "Person.New" instead of "new Person".
The "naming convention extension" that fits BOTH naming exceptions alike is: "every static method that starts with a capital letter is guaranteed to return a new instance of that type." Not a cached one. Always a new one. (this can be sometime crucial to guarantee the correctness of algorithms.)
This also has some neat side effects. For example:
The pseudo-constructor method for creating a new instance of
"StorageConfigurationBuilder" can be "StorageConfiguration.Builder()".
It is self-explaining, simple, clear.
Or if there is a method "public static Vector Normalized(Vector v)", it implicitely
tells that the passed instance will not be changed, but a new instance will
be returned for the normalized vector value. It's like having the
option to give constructors proper names all of a sudden. Instead of
a sea of different "Vector(...)" methods and having to rely on the
JavaDoc to indirectly explain their meaning, the explanation is right
there in the name. "New(...)", "Normalized(...)", "Copy(...)" etc.
AND it also plays along very nicely with the nested-Default-class
pattern: No need to write "new StorageConfiguration.Default()" (which
would be bad because too hardcoded, anyway), but just
"StorageConfiguration.New" suffices. It will internally create and
return a new "StorageConfiguration.Default" instance. And should that
internal logic ever change, it won't even be noticable by the API
user.
Why do I do that if no one else does?
If one thinks about it, that cannot be a valid argument. I stick VERY closely to standards and conventions as far as they make sense. They do about 99% of the time, but if they contain a problem (like forbidding a static method to be called "new") or lacking a perfectly reasonable feature (like PersonBuilder b = Person.Builder()" or choosing properly speaking names for constructors), then, after careful thought, I br... extend them as needed. This is called innovation. If no one else had that insight so far, bad for them, not for me. The question is not why an inventor creates an improvment, but why no one else has done it so far. If there is an obvious possibility for improvement, it can't be a valid reason not to do it just because no one else did it. Such a thinking causes stagnation and death of progress. Like locking oneself in a 1970ies data storing technology for over 40 years instead of just doing the obviously easier, faster, direct, better way.
I suggest to see the capital letter method naming extension as a testimony to innovation: If a new idea objectively brings considerably more advantages than disadvantages, it should - or almost MUST - be done.
I hereby invite everyone to adopt it.
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
I am starting to learn Android programming with Java, mainly from online Android documentation. I also looked through several books but they don't seem to address this issue: a feature of Java syntax which I have come across several times and which is a mystery to me. Here is just one example from about half-way through the Contacts Provider documentation at
http://developer.android.com/guide/topics/providers/contacts-provider.html
I have removed the comments to unclutter the code snippet:
op =
ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Email.ADDRESS, email)
.withValue(ContactsContract.CommonDataKinds.Email.TYPE, emailType);
This is all one statement, I think. What is confusing me is all those "dot operators" that look as though they belong in a Visual Basic "with clause". Where can I find out what all this means?
youre looking at a builder pattern, where the return value of each such with* method is the builder itself (or the object, if its not a builder exactly). theyre handly when you want to chain a lot of setters, or when there are a lot of constructors for the underlying object and you dont want people using it to get confused. or, as fge stated below, when you want the returned object to be immutable (so it cant have setters).
more specifically to your case, the return value of ContentProviderOperation.newInsert() is a ContentProviderOperation.Builder, all of who's methods return itself. usually such a chain of configuration calls will end in a call to build(), which will produce an operation.
This is an instance of so called fluent interfaces (link to wikipedia). There is noting special about it: the value returned from the previous call is being used as the target of the subsequent call.
API like this present a useful alternative to methods with lots of optional parameters, because the resulting code is much easier to read and understand. The code is somewhat more verbose, but in this case it is a good thing, because the parameters passed to constructors get better "tagging". This style is also preferable when you have multiple parameters of the same type (say, strings) next to each other, because it lets the readers avoid parameter counting.
each of those methods returns an ContentProviderOperation.Builder object that has been modified by the method. So you can chain together calls to methods like that and do everything in a more compact way. It's similar to how jQuery works in the javascript world.
It may clear things up a bit to look at the newInsert method on the Android documentation, then look at the documentation for the ContentProviderOperation.Builder class. note that all of the methods on that object also return ContentProviderOperation.Builder objects.
I have a class named ActivityLog. This class holds a list of ActivityRecords. I want to return a list of ActivityRecords by these criterias: Environment and Condition. Should the method name include the "criteria"? See example:
activityLog.allRecords();
activityLog.allRecordsBy(Environment environment);
activityLog.allRecordsBy(Condition condition);
activityLog.allRecordsBy(Condition condition, Environment environment);
or
activityLog.allRecordsByEnvironment(Environment environment);
activityLog.allRecordsByCondtion(Condition condition);
I probably think the first is better because you will read the method name and you will understand from the parameter what it does, but I may be wrong? Which is the best, or are there even better alternatives?
I could have named the methods records(), recordsBy etc. too, but I want to have a consitency through my API where you always start writing all for lists of objects so you get help from for example Intelli Sense.
I like putting the criteria in the actual method name. So I would use:
activityLog.allRecordsByEnvironment(Environment environment);
To me proper method naming expresses a small summary of what the method does. Since the parameters are included in the method signature I would not consider the parameters to be part of the actual name, therefore not placing the criteria in the name gives the user of an api incomplete information about the methods functionality. (IMO)
I applaud your effort to practice self documenting code, great practice.
I like the overloaded variant (your first example), because it communicates that the methods are all related and provide largely the same functionality, aka, you are returning records, filtered by some criteria. You will see examples of this in many open source libraries and even the SDK itself.
I'd treat it the same as static factory methods, which are named constructors. And there not only parameter says what this method does, its name itself does it. So I'd choose 2nd option.
#Bob, about names being too long - even if you would put 2 parameters into its name, it still would be ok for me. Anyway you should avoid having methods with more than 3 parameters. Following this rule will prevent your methods' names from being enormous long.
I would take the first one.
If these methods are doing the same thing or providing the same functionality then they should have the same name. But be aware of Effective Java Item 41 and 42. You've to ensure that at least one corresponding param of overloaded method are having radically different types.
The 2nd approach becomes ugly very fast with every param added. I see this in often in Broker classes at work. There are people writing methods like findByFirstnameAndLastnameAndBirthdayOrderByUgliness(blablub). No comment.
Methods in OOP represent behavior, so I would name all of them getRecords() and made them overloaded.
In my opinion, specifying criteria in the name of method looks like naming heirarchy classes like this
Car -> BMW_Car -> X5_BMW_Car
Let's say I've got a class called House with the two fields
name
address
Each of these fields has got a getter and a setter.
Now I want another method in the House class called setValues. This method should set the fields with properties from a passed object of a different type.
There would be two ways on how to create this method. First way:
private void setHouse(HouseTransfer transer){
name = transfer.getName();
address = transfer.getAddress();
}
Or the second option:
private void setHouse(HouseTransfer transer){
setName(transfer.getName());
setAddress(transfer.getAddress());
}
Which one is more "best practice"?
At a certain level of granularity, software design is more subjective matter than one of black-and-white absolutes. I do not believe there is an absolute "best practice" here.
That being said, I personally would use the second form. The basic idea of having a setter method is that at some point you might need some some special logic around setting that value (e.g. formatting input, sanitation, validation, etc). So it makes the most sense to always rely on any such logic being in one central place, rather than scattered throughout you code anywhere this variable is set.
If you have a truly trivial example, where the setter is simply setting the value and know absolutely that no other logic will ever be added, then you could certainly use the first form for simplicity. Put there's not real performance hit to the second form, so I personally would just use that.
I would use the individual getters/setters inside of the setHouse method (which is your second option).
The fact that you have setters indicates that there is some kind of encapsulation involved around that operation. Rather than re-write the code to enforce that encapsulation, re-use what you already have.
Jon's answer to that question (Taken from another question about using getters/setters which is not a duplicate to this one)
You don't always need getters/setters, but if you have some, there's usually a good reason why you've implemented them and in that case: use them.
Perhaps if you are getting and setting in two different places you might consider factoring out your getter and setter to a common interface. This can make later customisations easier, right?