According to Misko Hevery that has a testability blog. Developers should avoid 'holder', 'context', and 'kitchen sink' objects (these take all sorts of other objects and are a grab bag of collaborators). Pass in the specific object you need as a parameter, instead of a holder of that object.
In the example blow, is this code smell? Should I pass only the parameters that are needed or a model/bean with the data that I need.
For example, would you do anything like this: Note. I probably could have passed the data as constructor args. Is this a code smell?
public Parser {
private final SourceCodeBean source;
public Parser(final SourceCodeBean s) {
this.source = s;
}
public void parse() {
// Only access the source field
this.source.getFilename();
...
... assume that the classes uses fields from this.source
...
}
}
public SourceCodeBean {
private String filename;
private String developer;
private String lines;
private String format;
...
...
<ONLY SETTERS AND GETTERS>
...
}
...
Or
public Parser {
public Parser(String filename, String developer, String lines ...) {
...
}
}
And building a test case
public void test() {
SourceCodeBean bean = new SourceCodeBean():
bean.setFilename();
new Parser().parse();
}
Another question: With writing testable code, do you tend to write TOO many classes. Is it wrong to have too many classes or one class with too many methods. The classes are useful and have a single purpose. But, I could see where they could be refactored into one larger class...but that class would have multiple purposes.
You will also notice that Misko Hevery advises to group parameters in classes, whenever the parameter count increases or in cases where this is logically acceptable.
So in your case, you can pass the SourceCodeBean without remorse.
A lot of what you are asking is highly subjective, and it is difficult to make useful suggestions without knowing the full scope of what you are trying to accomplish but here is my 2 cents.
I would go with your latter design. Create one class called SourceCodeParser, have the constructor take in filename, developer, etc, and have it have a parse method. That way the object is responsible for parsing itself.
Typically I prefer to pass in parameters to the constructor if they are not too numerous. Code Complete recommends a max of 7 parameters. If you find the number of constructor parameters to be cumbersome you can always create setters off of the fore-mentioned SourceCodeParser class.
If you want a way to institute different parsing behavior I would recommend using a Parser delegate inside of SourceCodeParser and have that be passed in as either a constructor parameter or a setter.
If you have a class who's sole purpose is to associate together various pieces of information, then I see no reason why that class should not be used directly as a parameter. The reason being that the class was coded to do exactly that, so why would you not let it do its job? So I would definitely prefer the former.
Now, this is assuming that the Parser actually needs the information as it's semantically presented in SourceCodeBean. If all the Parser actually needs is a filename, then it should just take the filename, and I would prefer the second method.
I think the only thing that might worry me here is SourceCodeBean becoming a kind of "kitchen sink" of information. For instance, the filename and format fields make perfect sense here. But do you really need the developer and lines? Could those be instead in some sort of associated metadata-information class?
Related
I have two solutions to test my constructor (or setters).
The first is to use getters.
public void Test() {
Person p = new Person("toto"); // name
assertEquals("toto", p.getName());
}
The second is to use Field class
public void Test() {
Person p = new Person("toto"); // name
final Field fieldName = p.getClass().getDeclaredField("name");
fieldName.setAccessible(true);
assertEquals("toto", fieldName.get(p));
}
What is your recommendation and why? Thank you.
IMO, reflection should be avoided wherever possible. Of course there are some situations where it is needed, but in most situations it is not worth the large tradeoffs to performance and safety.
Secondly, and arguably more importantly, if the only way of testing a piece of code is to use reflection, then you probably don't need to test it.
Consider the following example:
public class Message {
private String message;
public Message(Message message) {
this.message = message;
}
// NO GETTERS/SETTERS
}
If I wanted to test that this constructor "works", I could write a test that uses reflection to look inside my object and checks to see if the message matches the constructor parameter. But what good is that?
Presumably, I want this message class to be consumed in some way by another piece of code. How does that code work? I will find that I probably need a getMessage() method or something equivalent to do anything useful with the object.
In general, using reflection in unit testing is bad because it tests the underlying implementation, rather than the behaviour. Your unit tests shouldn't break when someone comes along, for example, refactors the code to store the data on a remote server.
Also, I would avoid cluttering tests with "trivial" ones like this. Focus on testing your business logic. Trust the JVM to largely work as advertised.
You can use the very handy library called openpojo to automatically test POJOs.
https://github.com/OpenPojo/openpojo
I need a small Container-Class for storing some Strings which should be immutable. As String itself is an immutable type, I thought of something like that:
public final class Immu
{
public final String foo;
public final String bar;
public Immu(final String foo, final String bar)
{
this.foo = foo;
this.bar = bar;
}
}
Many people seem to object using public fields at all and use Getters instead. IMHO this would be just boilerplate in this case, because String itself is immutable.
Other thoughts I may be missing on this one?
I would do what you believe is simplest and clearest. If you have a data value class which is only used by a restricted number of classes. esp a package local class. then I would avoid getter/setters and use package local or public fields.
If you have a class which you expect other modules/developers to use, following a getter/setter model may be a safer approach in the long run.
The problem is the uniform access principle. You may later need to modify foo so that it's obtained through a method instead of being fixed, and if you exposed the field instead of a getter, you'll need to break your API.
This answer is obviated:
Why not
interface Immu { String getA() ; String getB ( ) }
Immu immu ( final String a , final String b )
{
/* validation of a and b */
return new Immu ( )
{
public String getA ( ) { return a ; }
public String getB ( ) { return b ; }
}
}
I found this thread hoping for some actual arguments, but the answers I've seen here didn't help me all that much. After some more research and thinking I think the following has to be considered:
public final looks cleanest for immutable types.
Mutable types could be altered by accessors even if this is not intended - in concurrent environments this could lead to a lot of headaches.
There can be no no-arguments constructor. This is importent if you need factory methods (e.g. for LMAX Disruptor). In a similar way instantiating your objects via reflection becomes more complicated.
Getters and setters can have side effects. Using public final clearly tells the programmer that no hidden magic is occuring and the object is inherently dumb :)
You can't return a wrapper or a derived class instance to the accessor. Then again, this is something you should know about when the field is assigned its value. In my opinion container classes should not be concerned about what to return to whom.
If you're mid development and no guideline is stopping you and the project is isolated or you have control over all involved projects I'd suggest using public final for immutable types. If you decide you need getters later on, Eclipse offers Refactor -> Encapsulate Field... which automatically creates these and adjusts all references to the field.
I use the public-final-field (anti?)pattern on home projects for classes which are basically an immutable data structure with a constructor, along with absolute basics like equals(), hashCode(), toString(), etc. if required. (I'm avoiding the word "struct" because of the various different language interpretations of it.)
I wouldn't bring this approach to someone else's codebase (work, public project, etc) because it would likely be inconsistent with other code, and principles like When In Rome or Least Surprise take priority.
That said, with regard to Daniel C. Sobral's and aioobe's answers, my attitude is that if the class design becomes a problem because of unforeseen developments, it's the work of 30 seconds in an IDE to privatise the fields and add accessors, and no more than 5 or 10 minutes to fix broken references unless there are hundreds of them. Anything that fails as a result gets the unit test it should have had in the first place.:-)
[Edit: Effective Java is quite firmly against the idea, while noting that it's "less harmful" on immutable fields.]
Forget about encapsulation, immutability, optimization and all other big words. If you are trying to write good java code, I would recommend you just use getter simply because it is java friendly, and most importantly it saves ton of time googling why.
For example, you probably would not expect using streams when you write the code, but later you found
listOfImmus.stream().map(immu -> imm.foo).collect(Collectors.toSet()); // with field
listOfImmus.stream().map(Immu::getFoo).collect(Collectors.toSet()); // with getter
Supplier<String> s = () -> immu.foo; // with field
Supplier<String> s = immu::foo; // with getter
// final fields are hard to mock if not impossible.
Mockito.when(immuMock.getFoo()).thenReturn("what ever");
//one day, your code is used in a java Beans which requires setter getter..
¯\_(ツ)_/¯
This list can be long or short or may be none of them makes any sense to your use case. But you have to spend time convincing yourself (or your code reviewers) why you can or should rebel against java orthodoxy.
It is better to just write the getter/setter and spent the time for something more useful: like complaining java
Since Java 16, you can use records.
public record Immu(String foo, String bar) {}
All of a record's attributes are automatically final and it automatically has methods like equals(…) and toString() and the constructor.
The getters of the attributes have the same name as the attributes, in this case, they are foo() and bar().
The methods can be overridden, more information is in the documentation.
It is not very clear if someone is going to use your code through an API.
You are also missing an opportunity to validate the input, if you are going to require some later.
Using public final may be fine for such small job, but it cannot be adapted as a standard practice,
Consider the situation below.
Public class Portfolio {
public final String[] stocks;
}
Of course, being immutable, this object is initialized vis constructor, and then accessed directly. Do I have to tell you the problem in it? It’s evident!
Consider your client writing the code like below -
Portfolio portfolio = PortfolioManager.get(“Anand”);
Portfolio.stocks[0] = “FB”;
portfolio.calculate();
Is this doable? Your client libraries are able to manipulate the state of your objects, or rather able to hack within your runtime representation. This is a huge security risk, and of course tools like SONAR catch it upfront. But its manageable only if you are using getter-setters.
If you are using getters, you can very well write
Public class Portfolio {
private final String[] stocks;
public String[] getStocks() {
return Arrays.coptOf(this.stocks);
}
}
This prevents you from potential security threat.
Looking at the above example, using public final is strongly discouraged if you are using arrays. In such case, it cannot become a standard. A person like me, will refrain from using a code practice that cannot become a uniform standard across all data types. What about you?
So I am writing a program right now and am conflicted about how I should program it. I have two options:
public class Translator {
private Translator(){}; //prevents instantation
/****
***Stuff
***/
public static String translate(String oldLanguage, String newLanguage, String text){
//METHOD Code
}
}
or
public class Translator {
private String oldLanguage;
private String newLanguage;
public Translator(String oldLanguage, String newLanguage){
this.oldLanguage = oldLanguage;
this.newLanguage = newLanguage;
};
/****
***Stuff
***/
public String translate(String text){
//METHOD Code
}
}
Which should I use and why? This will be the API end of my program.
Also, as programmer which do you find more convenient when dealing with APIs and why?
I would prefer to use the stateless version of translator, but I would prefer a state-full version of translated. The reason is, if you get rid of state then you can often get rid of an entire class of synchronization bugs while moving some of the important information closer to where it is actually used. Imagine, for example, if the two language variables were part of a 1000 line class. Would you want to look up how they are set every time they are used?
The reason I like state for translated is whereas a general translator can exist without knowing what languages it is going to be used for, if you lose what languages are used in a translated, you don't know as well what to do with it anymore (similar to losing your units in a math problem).
For the stateful option, a version I like better is, instead of:
...
private String oldLanguage;
private String newLanguage;
use:
...
private final String oldLanguage;
private final String newLanguage;
... and instead of something like:
myTranslator.setLanguages("spanish", "english")
Translated myTranslated = myTranslator.translate(original)
you can use:
Translator spanishEnglish = new Translator("spanish", "english")
Translated myTranslated = spanishEnglish.translate(original)
That's quite an interesting question, which doesn't have a single best answer. The criteria to choose, out of the top of my head, are mainly:
do you intend to instantiate a translator and reuse it several times with the same old and new languages?
does your translator need to keep some state in memory to be able to translate, without having to reload this state every time a translation is needed?
does your translator have other methods that also use the old and new languages?
is there somewhere in the application where the translator would have to be called without even caring/knowing about what the old and new language are, taking a pre-configured translator as argument?
do you need to be able to mock a translator and inject it in various other components of your code to unit-test them?
If the answers to these questions are yes, then a stateful translator (i.e. your second option) should be used. If the answers are no, then you could go with the first option.
As per the Object Oriented Programming standard, class is a representation of an entity. So you should define something as an attribute of class only if those are the properties of the entity represented by class. Having said that, add oldLanguage and newLanguage to your Translator class only if Translator entity has these attributes.
I would prefer to use the first one
public class Translator {
private Translator(){}; //prevents instantation
/****
***Stuff
***/
public static String translate(String oldLanguage, String newLanguage, String text){
//METHOD Code
}
}
why ?
the answer why should I instantiate an object to translate some thing if I can just do it directly .
Translator.translate(S,S,S);
A method of a class can (should?) be static when it does not access any non-static members or methods of this class.
Now this leads us to the question, when a member (field) of a class should be static or not:
A member (field) of a class must be non-static if it is relevant for defining the state of an instance (= object) of this very class.
So in summary, if something is relevant for the state of an object, then make it instance data, if not (only relevant for the calculation), then pass it as parameter into the method.
In addition to that, it becomes now clear, that it only makes sense to create an instance of a class, if you wish to represent a state. If zero non-static members exist, then you don't need to be able to create an instance of your class.
I need a small Container-Class for storing some Strings which should be immutable. As String itself is an immutable type, I thought of something like that:
public final class Immu
{
public final String foo;
public final String bar;
public Immu(final String foo, final String bar)
{
this.foo = foo;
this.bar = bar;
}
}
Many people seem to object using public fields at all and use Getters instead. IMHO this would be just boilerplate in this case, because String itself is immutable.
Other thoughts I may be missing on this one?
I would do what you believe is simplest and clearest. If you have a data value class which is only used by a restricted number of classes. esp a package local class. then I would avoid getter/setters and use package local or public fields.
If you have a class which you expect other modules/developers to use, following a getter/setter model may be a safer approach in the long run.
The problem is the uniform access principle. You may later need to modify foo so that it's obtained through a method instead of being fixed, and if you exposed the field instead of a getter, you'll need to break your API.
This answer is obviated:
Why not
interface Immu { String getA() ; String getB ( ) }
Immu immu ( final String a , final String b )
{
/* validation of a and b */
return new Immu ( )
{
public String getA ( ) { return a ; }
public String getB ( ) { return b ; }
}
}
I found this thread hoping for some actual arguments, but the answers I've seen here didn't help me all that much. After some more research and thinking I think the following has to be considered:
public final looks cleanest for immutable types.
Mutable types could be altered by accessors even if this is not intended - in concurrent environments this could lead to a lot of headaches.
There can be no no-arguments constructor. This is importent if you need factory methods (e.g. for LMAX Disruptor). In a similar way instantiating your objects via reflection becomes more complicated.
Getters and setters can have side effects. Using public final clearly tells the programmer that no hidden magic is occuring and the object is inherently dumb :)
You can't return a wrapper or a derived class instance to the accessor. Then again, this is something you should know about when the field is assigned its value. In my opinion container classes should not be concerned about what to return to whom.
If you're mid development and no guideline is stopping you and the project is isolated or you have control over all involved projects I'd suggest using public final for immutable types. If you decide you need getters later on, Eclipse offers Refactor -> Encapsulate Field... which automatically creates these and adjusts all references to the field.
I use the public-final-field (anti?)pattern on home projects for classes which are basically an immutable data structure with a constructor, along with absolute basics like equals(), hashCode(), toString(), etc. if required. (I'm avoiding the word "struct" because of the various different language interpretations of it.)
I wouldn't bring this approach to someone else's codebase (work, public project, etc) because it would likely be inconsistent with other code, and principles like When In Rome or Least Surprise take priority.
That said, with regard to Daniel C. Sobral's and aioobe's answers, my attitude is that if the class design becomes a problem because of unforeseen developments, it's the work of 30 seconds in an IDE to privatise the fields and add accessors, and no more than 5 or 10 minutes to fix broken references unless there are hundreds of them. Anything that fails as a result gets the unit test it should have had in the first place.:-)
[Edit: Effective Java is quite firmly against the idea, while noting that it's "less harmful" on immutable fields.]
Forget about encapsulation, immutability, optimization and all other big words. If you are trying to write good java code, I would recommend you just use getter simply because it is java friendly, and most importantly it saves ton of time googling why.
For example, you probably would not expect using streams when you write the code, but later you found
listOfImmus.stream().map(immu -> imm.foo).collect(Collectors.toSet()); // with field
listOfImmus.stream().map(Immu::getFoo).collect(Collectors.toSet()); // with getter
Supplier<String> s = () -> immu.foo; // with field
Supplier<String> s = immu::foo; // with getter
// final fields are hard to mock if not impossible.
Mockito.when(immuMock.getFoo()).thenReturn("what ever");
//one day, your code is used in a java Beans which requires setter getter..
¯\_(ツ)_/¯
This list can be long or short or may be none of them makes any sense to your use case. But you have to spend time convincing yourself (or your code reviewers) why you can or should rebel against java orthodoxy.
It is better to just write the getter/setter and spent the time for something more useful: like complaining java
Since Java 16, you can use records.
public record Immu(String foo, String bar) {}
All of a record's attributes are automatically final and it automatically has methods like equals(…) and toString() and the constructor.
The getters of the attributes have the same name as the attributes, in this case, they are foo() and bar().
The methods can be overridden, more information is in the documentation.
It is not very clear if someone is going to use your code through an API.
You are also missing an opportunity to validate the input, if you are going to require some later.
Using public final may be fine for such small job, but it cannot be adapted as a standard practice,
Consider the situation below.
Public class Portfolio {
public final String[] stocks;
}
Of course, being immutable, this object is initialized vis constructor, and then accessed directly. Do I have to tell you the problem in it? It’s evident!
Consider your client writing the code like below -
Portfolio portfolio = PortfolioManager.get(“Anand”);
Portfolio.stocks[0] = “FB”;
portfolio.calculate();
Is this doable? Your client libraries are able to manipulate the state of your objects, or rather able to hack within your runtime representation. This is a huge security risk, and of course tools like SONAR catch it upfront. But its manageable only if you are using getter-setters.
If you are using getters, you can very well write
Public class Portfolio {
private final String[] stocks;
public String[] getStocks() {
return Arrays.coptOf(this.stocks);
}
}
This prevents you from potential security threat.
Looking at the above example, using public final is strongly discouraged if you are using arrays. In such case, it cannot become a standard. A person like me, will refrain from using a code practice that cannot become a uniform standard across all data types. What about you?
I theoretically understand the point why there is no abstract static in Java, as explained for instance in Why can't static methods be abstract in Java .
But how do I solve such a problem then?
My application uses files of a few types, which I want to assign static properties like a description of that file type (like "data file", the other being "config file", etc.).
Obviously, I would put that into a static String so that the description is accessible without instancing a file (useful for the GUI f.i.).
On the other hand, obviously all file types should have some common methods like getStatus(), which obviously I want to inherit from a common superclass MyFileType.
getDescription() would of course be abstract in the superclass.
Tried using a combination of a superclass and an interface, but similar problem: A static implementation of an abstract method is not allowed.
How would a Java guru solve this?
Is it really such a bad implementation that I want to create?
Many thanks,
Philipp
To restate the problem: you want your per-file-type classes to have statically available information on the type (e.g., name and description).
We can easily get part-way there: create a separate class for your type info, and have a static instance of this (appropriately instantiated) in each per-file-type class.
package myFileAPI;
public class TypeInfo {
public final String name;
public final String description;
public TypeInfo(String name, String description) {
this.name = name;
this.description = description;
}
}
and, say:
package myFileAPI;
public class TextFile {
public static final TypeInfo typeInfo
= new TypeInfo("Text", "Contains text.");
}
Then you can do stuff like:
System.out.println(TextFile.typeInfo.name);
(Of course, you could also use getters in TypeInfo to encapsulate the underlying strings.)
However, as you said, what we really want is to enforce the existence of a particular signature static method in all your per-file-type classes at compile time, but the 'obvious' design path leads to requiring an abstract static method in a common superclass which isn't allowed.
We can enforce this at run-time though, which may be good enough to ensure it is coded correctly. We introduce a File superclass:
package myFileAPI;
public abstract class File {
public static TypeInfo getTypeInfo() {
throw new IllegalStateException(
"Type info hasn't been set up in the subclass");
}
}
If TextFile now extends File, we will get this exception when calling TextFile.getTypeInfo() at runtime, unless TextFile has a same-signature method.
This is quite subtle: code with TextFile.getTypeInfo() in still compiles, even when there is no such method in TextFile. Even though static methods are bound at compile time, the compiler can still look through the class hierarchy to determine the compile-time static call target.
So, we need code like:
package myFileAPI;
public class TextFile extends File {
private static final TypeInfo typeInfo
= new TypeInfo("Text", "Contains text.");
// Shadow the superclass static method
public static TypeInfo getTypeInfo() {
return typeInfo;
}
}
Note that we are still shadowing the superclass method, and so File.getTypeInfo() can still be 'meaninglessly' called.
This sounds like a great time to pull out the Fundamental Theorem of Software Engineering:
Any problem can be solved by adding another layer of indirection.
The problem you have right here is that a file carries around multiple pieces of information - what the type of the file is, a description of the file, the file contents, etc. I'd suggest splitting this into two classes - one class representing a concrete file on disk and its contents, and a second that is an abstract description of some file type. This would allow you to treat the file type class polymorphically. For example:
public interface FileType {
String getExtension();
String getDescription();
/* ... etc. ... */
}
Now, you can make subclasses for each of the file types you use:
public class TextFileType implements FileType {
public String getExtension() {
return ".txt";
}
public String getDescription() {
return "A plain ol' text file.";
}
/* ... */
}
You can then have some large repository of these sorts of objects, which would allow you to query their properties without having an open file of that type. You could also associate a type with each actual file you use by just having it store a FileType reference.
annotations could be fine for your purpose.
#FileProperties(desc="data file")
public class DataFile extends XFile { ... }
FileProperties props = DataFile.class.getAnnotation(FileProperties.class);
String desc = props.desc();
Accessing the info still requires reflection, however it's a little better than using static field/method.
Java compiler does not enforce that all subclasses are annotated as such. You can add your logic to the compiler (using annotation processing) but that's too complicated. It's ok to check it at runtime.
Update:
This is also possible:
#FileInfoClass ( DataFileInfo.class )
#public class DataFile
The question is not clear enough to provide an objective answer. Since I cannot give you a fish, this answer is more on the lines of "Teach you to fish" :)
When faced with design issues like these, where you think "duh..now sure why such a simple thing is so hard" more often than not, you are either designing it just incorrectly, or you are overcomplicating things. If I am empathizing correctly, your design issue seems like a "common requirement" yet the language is not allowing for any elegant solutions.
Trace back your design steps/decisions
question all the "obvious" and "of course" you are basing your design on (you are using quite a few above)
see if things can be simplified (don't take any of the OO concepts to their logical extreme. Make compromises based on ROI)
...and you will most likely arrive at an acceptable answer.
If you still don't, post back the classes and interfaces you think you want (with compile errors since language is not allowing certain things), and maybe we can help you tune your design.
I basically had the exact same problem.
You may want to look at the
solutions suggested to me in my question
I liked Bozho's idea, but according to himself it was a bad idea. :) I suppose better programmers can explain why it is so. Ralph's and Jon Skeet's solution also works.
Sounds like you need to use a singleton. Basically, you call a static method like MyFileTypes.getDataFileInstance() which creates a single instance (or reuses if already created) of an object and when you first create it setup the 'constants' as needed. I'll see if I can find you a good example but your post isn't very clear about how you want to use it.
You could create a FileMetadata class that has all the info you need. When your app starts up, you could create instances of FileMetadata, and keep static pointers to them so you can access them from anywhere in the JVM.
This way you put the abstract stuff in the actual instances; anything the stuff that does not call for abstract semantics can be static...
I don't know how a java guru would solve it, but I'd probably create a resource bundle with all the descriptions in a properties file like this:
com.bigcompany.smallapp.files.DataFile=Data file
com.bigcompany.smallapp.files.ConfigFile=Config file
Handling the bundle can conveniently be placed in the superclass or elsewhere.
Another option is to use reflection to access the static fields in each subclass, but then you need to make sure that all the subclasses have a static field with the same name.
There could be other options too, even refactoring the code so that the subtypes aren't represented by a separate class each, but in general there's no watertight solution.
Instead of putting your static properties actually in static properties, put a reference to MyFileTypeDescription as a static property.
i.e.
class MyFileType {
static MyFileTypeDescription description;
...
<your regular attributes>
}
abstract class MyFileTypeDescription {
String name;
abstract String getDescription();
}
Something along this way, if I understood your problem correctly.