3

hey i have a difficult question.

class DatabaseHelper { Database db; String defaultShema; public DatabaseHelper(Database db, String defaultSheme) { this.db = db; this.defaultShema = defaultShema; } public void databaseOperation1(String selectData, String FromData, String whereData) { // uses db and defaultShema } public void databaseOperation2(Database db, String shema, String selectData, String FromData, String whereData) { // uses parameter db and parameter shema } } 

if i use operation 1 then i use the field variables db und defaultShema

But what should i do if i have a special case; a case where i dont want to use the defaultShema or the default db.

for that case i must create a new DatabaseHelper.

And if i want to call my operation method 1000 times with different db/defaultShema variables each, then i have to instance 1000 temporary DatabaseHelper objects.

like this pattern

new object(...).doAction(); //after that delete 

So i have operation2, but this one uses lesser till nothing state from the sourounding class. Here i dont have to create thousands of senseless instances of DatabaseHelper. But maybe this method could also exists as a static method, if BOTH db and defaultSchema is used from the method-parameter-set. But maybe i want only use one of them from the parameter-set the other one from the field-set of the class.

So here my question, when should i make variables to fields and when to method-parameters? Maybe in most of the cases the selectData is identical. So i would make that parameter to a field.

But there i have the problem that other methods, for example insert-methods dont need that field -> unncecessary internal class dependancy.

i used here a example with the Database. But i guess that problem is very common with other classes like this.

If i use always operation 2, then i dont need classes anymore -> i only have static methods.

But if i use opertion 1 like methods, then i have to decide which variables i have to make to fields. But which?

And that one i make to fields, in some cases, i dont want to use them in default mode; so i want to change them

But i guess the following is nonsense:

String tmp=db.getDefaultSchema(); db.changeStateOfDefaultSchema("XYZ"); db.databaseOperation1(...); db.changeStateOfDefaultSchema(tmp); //OR new DatabaseHelper(..., "XYZ").databaseOperation1(...); //GC -> delete of that tmp DatabaseHelper 

So how should i design my classes? Which variables should i make to fields and which one to method parameter What should i do if i want to have the flexibilty to change later each of that variables; if i dont know yet, which variables the client have to change often and which one not so often.

    2 Answers 2

    2

    Your class is a helper class. Appending this suffix prepares me to treat this class as a class containing code that you didn't have anywhere else to put, because it was so general-purpose that it should probably not belong to any other class in the game of object-oriented design. This is not bad. Helper classes are, often, static classes with extension methods (or just static methods in general). Sometimes they are not. Classes that are not helpers are, of course, the only thing that's left: protagonists.

    In any case, the answer to your question is the same trite answer you may hear time and again: It depends. What is it that you are trying to achieve? If you have to create a new object, use a method and then the object's lifetime ends, you are wasting resources. What is a good way to not waste resources, then?

    • Make the method static, you don't need an unnecessary instantiation each time you only need one completely "impersonal" method call.

    What's that whisper? Do I hear a comment about compiler optimizationsTM?

    Fair point, but object-oriented programming means writing code that means something to humans, not thinking about compilers and technicalities. If all you cared about was how to drive to work, would you order a new car every day (and then dispose it)? You would probably consider static methods (e.g. a bus you don't own, maybe the same every day). In the object-oriented context, creating an object just to use one of its methods, which, by the way, utilize absolutely no state (i.e. private fields) from the object itself, just makes no sense. It offers absolutely nothing. Yes, you can do it, classes are the abstraction when it comes to object-oriented programming. But this is not increasing flexibility. It just takes code from one file and places it in another file.

    Maybe that's what you wanted. You have a repetitive method, you need to make your files smaller. You get the pieces that look like repetitive code and put them in one place. Good, great even! DRY is a good practice. The bonus points you get by Not-Repeating-Yourself have to do with clarity, maintainability, portability... but you do not get any conceptual flexibility. Old-school programming (structural, pre-OOP) was based on dozens (if not hundreds) of functions with code. Functions were the abstraction unit of the era. But people noticed that functions, as an abstraction unit, do not give much conceptual flexibility. You still need to call a specific function at some point in your code, or maybe decide on a function and call it. It is not like having the piece of code that calls a method not even knowing what the method does or where the actual code is written (because it may be spread around in multiple places, as in "multiple implementations").

    This brings me precisely to the answer to your question: You use fields instead of parameters when you want to make your class mean something, i.e. hold state. A stateless class is not an instance, it is a portable code repository. And just because compilers and computers are artificially smart and do not duplicate code for instances of the same type, this is not what happens in real life. Suppose a shop hands out free cookbooks and you are one person. If you get two copies of the same cookbook, you have two cookbooks, double the number of pages, and you need double the storage space, than if you had bought only one copy. It doesn't make sense if you only want to cook. It's a waste of resources and, even though it costs a tiny little bit in terms of memory overhead, it just makes little sense to instantiate an object just for the code. Someone reading through the code (for maintenance purposes) will try to understand what is hiding behind the instance and will be puzzled (cf. principle of least astonishment) to find nothing special. A static method in a static class makes your intentions far more explicit.

    In short, if there is something that you want to maintain a reference to, because you might need it later, then it is something you would store in a private field. If you have some purpose for them, that is. For example, if you "risk" making the same query into a database, which has already been made before, and you also know that the database has not changed between queries, you can store the query response inside the class (in a Map, for example) and return it immediately. If the query is new, you can cache the result. These functionalities necessitate storing state variables for a class, which can, then, offer them "undercover". These are just some examples. The general answer remains valid: when you want to formulate a class that stores state (which may or may not be alterable), you store this state in private fields. And whether you need to store state or not depends on what exactly it is that you are modelling, and how you would like it modelled.

    If we were to judge object-oriented programs bearing technicalities in mind, we would miss on the greatest advantages object-oriented design offers, such as, among others, clarity and readability.

    0
      2

      There are several things you should consider; these might help you to decide whether to use fields or method parameters:

      • Should the values be shared among similar calls?
        If yes, then make them fields and do not pass them each time as parameters.
        In this case, using fields avoid repetition and prevents mistakenly using the wrong value.
      • Are the two (or more) values closely related (and do they form a concept)?
        If yes, then
        • Is the caller this concept?
          If the caller is not this concept, then make the values fields. This using a higher level of abstraction in the calling code and thus can help with adhering to the single responsibility principle. It helps to prevent using the wrong combination of values.
      • Are you (at every call site) creating an object instance, setting the fields (via constructor or properties, calling the same method, and then discarding the object without any other logic that belongs in between?
        If yes, then use method parameters. Vector Zita has a good point: just creating an object, setting its fields, and immediately using it once is wasteful. IMHO, the cognitive burden you cause to you code's readers is worse than the possible extra computations.

      A static method that receives all its input via parameters is easier to test, since it is insulated from side-effects of other methods. It is also less likely to introduce side-effects itself.
      You can combine the advantages of a static method's testability and an instance method's encapsulation by providing both and having the instance method forward to the static method.

      If you choose to combine the values into fields of some object, you have to decide if the values (database and schema in the example) and the operations (dabaseOperation1) should belong to the same class or that the operation accepts the values-object as parameter: * Is the ...Helper-class actually a bag of not very closely related procedures for which no better place was found?
      If yes, that would make moving some of them into a coherent class an improvement. * Would (a subset of) the methods in DatabaseHelper and the fields database and schema form a coherent unit? And do the operations make sense as something a database and schema object can do? If yes, then combine the fields and the (subset of the) fields.

      Look into the fly-weight pattern where they do use something like your database and schema parameters, especially read the part on when to use the fly-weight pattern, what it brings you, and its trade offs.

      0

        Start asking to get answers

        Find the answer to your question by asking.

        Ask question

        Explore related questions

        See similar questions with these tags.