• Post Reply Bookmark Topic Watch Topic
  • New Topic

Worried about creating classes for a single use.  RSS feed

 
Avor Nadal
Ranch Hand
Posts: 156
Java Netbeans IDE Postgres Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
IMPORTANT: This question is about choosing to return an instance of a dedicated class or altering the passed argument.


Hello:

Very often I need to set the attributes of an object with values that come from the call to a private method. I use this method to encapsulate the logic that builds such values. When I've found this kind of situation, I've made a class to hold the values that I've just built in the private method, and I've returned an instance of it to the callee. There I've used this container to set the attributes of the object in question.

However, for the last days, I've doubted if it's the most convenient way and I've wondered if another approach could be easier or clearer to read and maintain.

To illustrate it let's suppose that I've a public method that constructs an instance of a class, called Email, which has the attributes "recipients", "subject", "body". The private method "createEmailContent", depending on the type of recipient, creates a different subject and body:

APPROACH A



Now the code that could replace the one above:

APPROACH B



I've thought about their pros and cons:

  • Approach A: It follows the principle that says that a method should do one action only. Because it's agnostic towards the class Email, it could be re-used for other purposes, although it's improbable in this case. It receives several operands and returns one result, which is easy to understand. The only "problem" in my opinion is that it forces you to make a class of a single use every time that you want to use it, making your application bigger in terms of code and memory consumption.


  • Approach B: It avoids the need of a container class. It could choose the most suitable setter by itself, in case that the object in question had several ones for the same "concept". For example, for some recipients it could use a method called "setTextPlainBody ()", whereas for others it could use "setMultiPartBody ()". You also can do this in the approach A, but in the callee.


  • Which approach is better in your opinion and why? Doesn't it make sense to worry about the number of these type of classes?

    Thank you.
     
    Bear Bibeault
    Author and ninkuma
    Marshal
    Posts: 66307
    152
    IntelliJ IDE Java jQuery Mac Mac OS X
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Which improves the clarity of the code?
     
    Avor Nadal
    Ranch Hand
    Posts: 156
    Java Netbeans IDE Postgres Database
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Bear Bibeault: I believe that the approach B is a little more readable, whereas the approach A seems much more proper in terms of conceptualization.

    By "conceptualization" I mean that in Java it's common to pass some arguments to a method and obtain a result, instead of passing arguments to it and altering the content of one of them, Right?

    In the approach A the code of the private method is also self-documented, because no argument is altered. It's the expected behaviour. Maybe it's not as much important in a private method as it's in a public one, but I believe that it's a good practice.

    The approach A also allows to work with immutable objects, both the value that you return and the object in the callee method. The approach B requires to use a mutable object in the callee necessarily.

    Which strategy do you follow when you program? How much overhead do these classes add (in the HotSpot JVM)?

     
    Red Smith
    Ranch Hand
    Posts: 136
    1
    Netscape Opera Ubuntu
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Is createEmail being used (versus a constructor) so that in the future subclasses of email will be created based on the parameters to it?

     
    Avor Nadal
    Ranch Hand
    Posts: 156
    Java Netbeans IDE Postgres Database
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Red Smith: I guess that I should have clarified that, sorry. "createEmail" is a method of an utility class that has nothing to do with Email. It's only used to encapsulate code that is going to be used in many places of my application.
     
    E Armitage
    Rancher
    Posts: 989
    9
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Avor Nadal wrote:

    Which strategy do you follow when you program? How much overhead do these classes add (in the HotSpot JVM)?



    Forget about overhead added to Hotspot until you actually encounter a performance problem.

    If you are building complex objects there are (generally speaking) two types of patterns. The builder pattern or the (abstract) factory pattern. read up on both to decide which one is applicable for your scenarios.
     
    Avor Nadal
    Ranch Hand
    Posts: 156
    Java Netbeans IDE Postgres Database
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    E Armitage: I understand your answer. However, my question is about choosing between returning an object of a dedicated class, or altering the passed argument. The use of "createEmail" is just circumstantial in this case. I'm sorry for not having made it clear from the beginning.

    But thank you for the help.
     
    E Armitage
    Rancher
    Posts: 989
    9
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Avor Nadal wrote:E Armitage: I understand your answer. However, my question is about choosing between returning an object of a dedicated class, or altering the passed argument. The use of "createEmail" is just circumstantial in this case. I'm sorry for not having made it clear from the beginning.

    But thank you for the help.

    Did you read about the builder pattern then to see why it's relevant?
    Also, why does one approach result in more classes than the other? The createEmail method could be put in the Email class or some other sensible class and you would have the same number of classes in either approach?
     
    Red Smith
    Ranch Hand
    Posts: 136
    1
    Netscape Opera Ubuntu
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Avor Nadal wrote:Red Smith: I guess that I should have clarified that, sorry. "createEmail" is a method of an utility class that has nothing to do with Email. It's only used to encapsulate code that is going to be used in many places of my application.


    What is the advantage of having a createEmail static method in the utility class, versus making an Email constructor that takes the same parameters?
     
    Avor Nadal
    Ranch Hand
    Posts: 156
    Java Netbeans IDE Postgres Database
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    E Armitage: Yes, I did. I didn't ignored your answer, trust me ;) . But I didn't choose the builder pattern because I could and wanted to build the instance in a single step.

    E Armitage and Red Smith: The problem not to use a custom constructor or move "createEmail" inside of the class Email is that it's part of an external API. I should have mentioned it in my example, sorry.
     
    Red Smith
    Ranch Hand
    Posts: 136
    1
    Netscape Opera Ubuntu
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    The problem not to use a custom constructor or move "createEmail" inside of the class Email is that it's part of an external API. I should have mentioned it in my example, sorry.



    Is a custom constructor a constructor that takes parameters or are you saying you don't want to modify the Email class from what it already is? For instance, by making a constructor for Email that takes all three parameters to createEmail and adding either of the static methods to Email as a regular method?
     
    Avor Nadal
    Ranch Hand
    Posts: 156
    Java Netbeans IDE Postgres Database
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Red Smith: I'm sorry for making you all spend your time, but English is not my native language.

    I mean that the class Email is not editable by me. It comes from an external API. Think about it as if it were the class MimeMessage of the package javax.mail. Instead of instantiating it and setting its attributes manually every time that I need it, I have created a helper method called "createEmail" in an utilities' class which does that in a single line. For example, 2 methods of an arbitrary class of my application would use that method this way:

     
    Red Smith
    Ranch Hand
    Posts: 136
    1
    Netscape Opera Ubuntu
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I would have chosen B in the past since I had no qualms about passing in parameters that were updated. However, the current talk of functional programming and pure functions makes me prefer functions that do not update their parameters and reflect all work in their return value. So I would choose A because of the parameter update in B.


    You didn't ask for any code suggestions, but with regard to the EmailContent class, since the Email() class has a default constructor, I think you could create an Email in the helper function and avoid a separate class to pass back the data in A and also avoid updating a parameter as in B. Although the name of the function is problematic:




    Also, maybe the EmailContent class could be a nested/inner/local class declared inside of createEmail() since it has no purpose outside of that function. Although the static createEmailContent would have to become a part of EmailContent.
    The nested class could do all the work, with the createEmail() method just creating one (passing the three parameters to it's construcdtor) and then getting the newly created Email from it.

     
    Avor Nadal
    Ranch Hand
    Posts: 156
    Java Netbeans IDE Postgres Database
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hello. Finally I decided to continue using the approach A, except in very specific cases. I counted how many times I used these auxiliary classes and came to the conclusion that they were not so many after all. I feared that the number increased too much in my project, but it didn't.

    Thank you all for your comments and ideas .


    Red Smith: My approach A is very similar to the one that you describe in your last comment indeed . Although I prefer to use the inner class just as a container and put the logic in a private method of the parent class. I'll take your comments into account anyway and see what option is more readable for me. Thanks ;) .
     
    Don't get me started about those stupid light bulbs.
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!