When to use parameters and when to use instance data? - java

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.

Related

Do we need get/set method for enum? [duplicate]

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?

How can I initialize interdependent final references?

I have a class and a factory function that creates new anonymous class objects extending that class. However, the anonymous class objects all have a method in which there are references to other objects. In my full program, I need this to create and combine parsers, but I've stripped down the code here.
class Base{
public Base run(){
return null;
}
static Base factory(final Base n){
return new Base(){
public Base run(){
return n;
}
};
}
}
public class CircularReferences{
public static void main(String args[]){
final Base a, b;
a = Base.factory(b);
b = Base.factory(a);
}
}
I get CircularReferences.java:17; error: variable b might not have been initialized. That's true, it wasn't, but can't I set aside space for these variables and then initialize them using references to these spaces, which will be filled with the proper values before they are ever actually used? Can I perhaps use new separately from the constructor? How can I create these variables so they reference each other?
The quick answer is that you can't do this. If you absolutely must do something like this, then use a private setter on the class and bind things together after they are constructed (i.e. use enforced immutability instead of final fields). Hopefully it's obvious that I don't think this is a good idea - I just wanted to provide a answer to your actual question before I answer the way that I really want to.
OK - now that is out of the way, here's the real response that is called for here:
Generally speaking, this sort of situation is a strong indicator that refactoring is needed to separate concerns. In other words, the Base class is probably trying to be responsible for too many things.
I realize that the example is contrived, but think about what functionality requires the circular dependency, then factor that functionality out into a separate class/object that then gets passed to both of the Base constructors.
In complex architectures, circular dependency chains can get pretty big, but strictly forcing final fields is great way to look for those types of refactoring opportunities.
If you have a concrete example, I'd be happy to help with some refactoring suggestions to break a dependency like this.
concrete example provided - here's my suggestion:
It seems like there is a concern of obtaining an appropriate ParseStrategy based on a token. A ParseStrategyProvider. So there would be a TopLevelParseStrategy that reads the next token, looks up the appropriate parse strategy, and executes it.
TopLevelParseStrategy would hold a final reference to the ParseStrategyProvider.
The ParseStrategyProvider would then need to have a registration method (i.e. registerStrategy(token, parseStrategy) ).
This isn't functionally much different from doing this with enforced immutability via a private setter (the registerStrategy method is for all intents and purposes the same as the private setter), but the design is much more extensible.
So you'd have:
public ParseStrategy createParser(){
ParseStrategyProvider provider = ParseStrategyProvider.create();
TopLevelParseStrategy topLevel = new TopLevelParseStrategy(provider);
provider.registerStrategy("(", topLevel);
// create and register all of your other parse strategies
return topLevel;
}

when exactly are we supposed to use "public static final String"?

I have seen much code where people write public static final String mystring = ...
and then just use a value.
Why do they have to do that? Why do they have to initialize the value as final prior to using it?
UPDATE
Ok, thanks all for all your answers, I understand the meaning of those key (public static final). What I dont understand is why people use that even if the constant will be used only in one place and only in the same class. why declaring it? why dont we just use the variable?
final indicates that the value of the variable won't change - in other words, a constant whose value can't be modified after it is declared.
Use public final static String when you want to create a String that:
belongs to the class (static: no instance necessary to use it), that
won't change (final), for instance when you want to define a String constant that will be available to all instances of the class, and to other objects using the class, and that
will be a publicly accessible part of the interface that the class shows the world.
Example:
public final static String MY_CONSTANT = "SomeValue";
// ... in some other code, possibly in another object, use the constant:
if (input.equals(MyClass.MY_CONSTANT)
Similarly:
public static final int ERROR_CODE = 127;
It isn't required to use final, but it keeps a constant from being changed inadvertently during program execution, and serves as an indicator that the variable is a constant.
Even if the constant will only be used - read - in the current class and/or in only one place, it's good practice to declare all constants as final: it's clearer, and during the lifetime of the code the constant may end up being used in more than one place.
Furthermore using final may allow the implementation to perform some optimization, e.g. by inlining an actual value where the constant is used.
Finally note that final will only make truly constant values out of primitive types, String which is immutable, or other immutable types. Applying final to an object (for instance a HashMap) will make the reference immutable, but not the state of the object: for instance data members of the object can be changed, array elements can be changed, and collections can be manipulated and changed.
Static means..You can use it without instantiate of the class or using any object.
final..It is a keyword which is used for make the string constant. You can not change the value of that string. Look at the example below:
public class StringTest {
static final String str = "Hello";
public static void main(String args[]) {
// str = "world"; // gives error
System.out.println(str); // called without the help of an object
System.out.println(StringTest.str);// called with class name
}
}
Thanks
The keyword final means that the value is constant(it cannot be changed). It is analogous to const in C.
And you can treat static as a global variable which has scope. It basically means if you change it for one object it will be changed for all just like a global variable(limited by scope).
Hope it helps.
static means that the object will only be created once, and does not have an instance object containing it. The way you have written is best used when you have something that is common for all objects of the class and will never change. It even could be used without creating an object at all.
Usually it's best to use final when you expect it to be final so that the compiler will enforce that rule and you know for sure. static ensures that you don't waste memory creating many of the same thing if it will be the same value for all objects.
final indicates that the value cannot be changed once set. static allows you to set the value, and that value will be the same for ALL instances of the class which utilize it. Also, you may access the value of a public static string w/o having an instance of a class.
 public makes it accessible across the other classes. You can use it without instantiate of the class or using any object.
 static makes it uniform value across all the class instances.
It ensures that you don't waste memory creating many of the same thing if it will be the same value for all the objects.
 final makes it non-modifiable value. It's a "constant" value which is same across all the class instances and cannot be modified.
You do not have to use final, but the final is making clear to everyone else - including the compiler - that this is a constant, and that's the good practice in it.
Why people doe that even if the constant will be used only in one place and only in the same class: Because in many cases it still makes sense. If you for example know it will be final during program run, but you intend to change the value later and recompile (easier to find), and also might use it more often later-on. It is also informing other programmers about the core values in the program flow at a prominent and combined place.
An aspect the other answers are missing out unfortunately, is that using the combination of public final needs to be done very carefully, especially if other classes or packages will use your class (which can be assumed because it is public).
Here's why:
Because it is declared as final, the compiler will inline this field during compile time into any compilation unit reading this field. So far, so good.
What people tend to forget is, because the field is also declared public, the compiler will also inline this value into any other compile unit. That means other classes using this field.
What are the consequences?
Imagine you have this:
class Foo {
public static final String VERSION = "1.0";
}
class Bar {
public static void main(String[] args) {
System.out.println("I am using version " + Foo.VERSION);
}
}
After compiling and running Bar, you'll get:
I am using version 1.0
Now, you improve Foo and change the version to "1.1".
After recompiling Foo, you run Bar and get this wrong output:
I am using version 1.0
This happens, because VERSION is declared final, so the actual value of it was already in-lined in Bar during the first compile run. As a consequence, to let the example of a public static final ... field propagate properly after actually changing what was declared final (you lied!;), you'd need to recompile every class using it.
I've seen this a couple of times and it is really hard to debug.
If by final you mean a constant that might change in later versions of your program, a better solution would be this:
class Foo {
private static String version = "1.0";
public static final String getVersion() {
return version;
}
}
The performance penalty of this is negligible, since JIT code generator will inline it at run-time.
Usually for defining constants, that you reuse at many places making it single point for change, used within single class or shared across packages. Making a variable final avoid accidental changes.
Why do people use constants in classes instead of a variable?
readability and maintainability,
having some number like 40.023 in your code doesn't say much about what the number represents, so we replace it by a word in capitals like "USER_AGE_YEARS". Later when we look at the code its clear what that number represents.
Why do we not just use a variable? Well we would if we knew the number would change, but if its some number that wont change, like 3.14159.. we make it final.
But what if its not a number like a String? In that case its mostly for maintainability, if you are using a String multiple times in your code, (and it wont be changing at runtime) it is convenient to have it as a final string at the top of the class. That way when you want to change it, there is only one place to change it rather than many.
For example if you have an error message that get printed many times in your code, having final String ERROR_MESSAGE = "Something went bad." is easier to maintain, if you want to change it from "Something went bad." to "It's too late jim he's already dead", you would only need to change that one line, rather than all the places you would use that comment.
public makes it accessible across other classes.
static makes it uniform value across all the class instances.
final makes it non-modifiable value.
So basically it's a "constant" value which is same across all the class instances and which cannot be modified.
With respect to your concern "What I don't understand is why people use that even if the constant will be used only in one place and only in the same class. Why declaring it? Why don't we just use the variable?"
I would say since it is a public field the constant value can also be used elsewhere in some other class using ClassName.value. eg: a class named Math may have PI as final static long value which can be accessed as Math.PI.
It is kind of standard/best practice.
There are already answers listing scenarios, but for your second question:
Why do they have to do that? Why do they have to initialize the value as final prior to using it?
Public constants and fields initialized at declaration should be "static final" rather than merely "final"
These are some of the reasons why it should be like this:
Making a public constant just final as opposed to static final leads to duplicating its value for every instance of the class, uselessly increasing the amount of memory required to execute the application.
Further, when a non-public, final field isn't also static, it implies that different instances can have different values. However, initializing a non-static final field in its declaration forces every instance to have the same value owing to the behavior of the final field.
This is related to the semantics of the code. By naming the value assigning it to a variable that has a meaningful name (even if it is used only at one place) you give it a meaning. When somebody is reading the code that person will know what that value means.
In general is not a good practice to use constant values across the code. Imagine a code full of string, integer, etc. values. After a time nobody will know what those constants are. Also a typo in a value can be a problem when the value is used on more than one place.
I think these are all clear explanations. But, Let me clarify it by giving a java inbuild example.
In java, most would have used System.out.println()
The system is a class and out is a PrintStream class.
So what java says is I will take care of the initialization of the out object(PrintStream) and keep the initialization private to myself in the System class.
public final class System {
public final static PrintStream out = null;
//Some initialization done by system class which cannot be changed as it is final.
}
You just access the println method statically without worrying about its initialization.

Immutable Type: public final fields vs. getter

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?

Testable Java Code: using model beans with a constructor

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?

Categories

Resources