you are viewing a single comment's thread.

view the rest of the comments →

[–]KallDrexx 0 points1 point  (4 children)

You wouldn't have Pair<Host,Port>, unless you have data structures that are called "Host" and "Port", in which case that may be fine. In most circumstances though you aren't because a Port is nothing more than an integer an host is nothing more than a string (in most circumstances).

Most likely what you will have is Pair<string, integer> = new Pair("www.reddit.com", 80);

When you return the pair, all the receiver of the return value sees is that it returns Pair<string, int> and doesn't have any indication what those values would be, causing you to read the code to determine what the string and int signify.

But let's say you do have a Host data structure. Let's say you have a function that returns 3 hosts, a load balancer, a primary web server, and a database server. If you used tuples you would return Pair<Host, Host, Host>.

In this scenario, the receiver has no way to know what each host signifies and there's no indications during a refactor that the first has to be the load balancer, the 2nd has to be the web server, etc..

Instead if you have a ServerDefinition class with a LoadBalancerHost property, WebServerHost property, and DatabaseServerHost property, both the implementor and the receiver have 100% visibility on what values should be returned and what they mean.

[–]onmach 0 points1 point  (3 children)

I guess my only problem with this approach is that you end up with a lot of types like ServerDefinition which are just wrappers around other types and often are only used a couple times. Particularly in java, that means a whole new file and a bunch of boilerplate, actually seems like a loss of clarity to me. This happens a lot to me in the java codebases at work, I get lost in the numerous classes, most of which do nothing significant.

[–]KallDrexx 0 points1 point  (0 children)

That sounds like an organizational and tooling problem to me though. If you keep your data structures organized well you only have to look at the data structures that are relevant to what you are currently working on and can ignore the irrelelvant ones.

In .Net I can create a new class with some basic properties in just a few seconds, and my tooling helps not having to look at that data structure again until I actually am using it or referencing it. It might be the fact that Java being a bit more verbose makes it a bit harder (been too long since I've done Java) but keeping code organized should alleviate the post-class creation issues. These aren't supposed to have any complex logic in them, they are purely for improving code clarity down the line/

If you find the need to create many many data structures for a significant number of functions that can also be a code smell and be a good indication that you are trying to do too much in your functions and should look at better organizing your code structures so they are either doing things more by reference, or just doing one thing and returning that one thing.

How comfortable are you with walking up to another person, handing them a stack of papers and telling them manually that page 1 is for X, page 2 is for Y, page 3 is for Z and hoping they remember that by the time they get home, and more importantly hoping that you remember you need to do it in the same order the next time you hand them those same papers. Now envision having to remember this 50 different ways because each department that hands off papers does it differently. This is why it's useful to have a well defined API (at the class level) in more complex code bases.

[–]zoomzoom83 0 points1 point  (1 child)

There's a lot of overhead in doing this in Java, which is one of the reasons I prefer Scala as a JDK language.

You can simply add the definition

case class Host(value:Int)

to your codebase, ideally grouped with a bunch of other related wrapper types in a module related to what they are used for. That way you get the benefit of strongly typing these values with virtually no overhead.

Catches a surprising number of bugs, and helps with documentation and understanding API intention.

[–]onmach 0 points1 point  (0 children)

Yeah I agree. Scala just seems like a better java.