I would argue that each instance should remain stateless once it is constructed, i.e., it should not maintain extra state across invocations that changes based on the parameters. A classic example is a tax calculator.
interface TaxCalculator {
/**
* Calculates the tax for the given purchase price and shipping charges.
* All values are in pennies to avoid rounding.
*
* @param subtotal total price of all items ordered
* @param shipping cost of shipping the order
* @return calculated tax
*/
int calculate(int subtotal, int shipping);
}
class NoTax implements TaxCalculator {
public int calculate(int subtotal, int shipping) {
return 0;
}
}
class FixedPercentOfSubtotal implements TaxCalculator {
private final int ratePercent;
public FixedPercentOfSubtotal(int ratePercent) {
this.ratePercent = ratePercent;
}
public int calculate(int subtotal, int shipping) {
return subtotal * ratePercent / 100;
}
}
While FixedPercentOfSubtotal
has a member (state), it's provided at construction time and never changes. You could store one instance per state, making them quasi-singletons.
Update
Neither the Wikipedia article nor this Strategy Pattern page make any stipulation that implementations should not maintain state across calls. It's less common because strategies are designed to be interchangeable and pluggable at runtime, but I wouldn't rule it out.
However, that you needed to add a new method to enable that one strategy implementation is a red flag. Other implementations may not need it. Will you define it in the interface anyway? It may make more sense to have the historical-tracking strategy implement RaceListener
and add it to the race track instance. This would allow it to be shared among multiple users as a singleton.
In my projects, I give them a name but not necessarily a domain. So my package names (and namespaces) are usually just "projectname.libraryname", regardless where the code is hosted.
I am used to .NET where this is handeled quite freely.
Best Answer
Guidelines are guidelines, not immutable laws of nature. You have found an excellent example of a sensible name that cannot be easily mapped into the normal Java naming conventions. So what should you do?
Make an exception.
Of all your suggestions,
Iso8859_1
is the only name that clearly and unambiguously expresses what the class is about. The various coding guidelines are just heuristics to find clear names. Here they fail, and you would do well to ignore them.Checkstyle is configurable. Either adapt the config to allow such names, or except the class declaration from the name check. Make the tool help you, instead of making yourself slave to an incompetent tool.
(Rationale: The default Java coding conventions suggest the use of camelCase to visually emphasize word boundaries within an identifier. Underscores are used as word boundaries in constants because constants should be all-uppercase. Here you need a boundary between digits. As ASCII digits don't have case you can't use camel case here, and by elimination the only remaining option to separate digits in a name is underscores.)