Defining states for a FSM with n states. (java) - java

I have never worked with enum State before and recently came across it, I've found that to define a FSM where YOU, the programmer, knows the states the code is something like this:
enum States {state0, state1, state2}; //an example of a state machine with 3 states as defined by the programmer.
but I want to be able to define a FSM where the user decides how many and what states there are, is there a way to do this?

You cannot use enums here, which have a fixed size, but I guess you can do something like this :
public class StateMachine {
// it is up to you to define what a State and a Transition are
private Set<State> possibleStates;
private Set<Transition> transitions;
private State currentState;
// methods for adding and removing states
// ...
// methods for adding and removing transitions
// ...
}

Unfortunately, there is no great way to make run-time enums. There are, however a few other options:
Use an int to represent your state. This is simple and efficient, but can be confusing and difficult to understand later, as an int doesn't tell you much about what the state means. This can be partially mitigated by storing a map from Integer(state) to String (description of that state)
Create an immutable class to represent a state, or wrap an existing one like String. Make instances of the class only available through a static factory method which restricts the states given out to the subset you need, and internally keep a set of all instances, providing them when the same state is asked for twice from the factory method.This will allow equality comparison by reference, and creates similar semantics to enums.
There is the separate problem (which arises on both options) of deciding on action based on state, because the state is only defined at runtime, you cannot use a switch statement. A linear search, equivalent to chained if statements, scales poorly with the number of states. This problem can be solved by creating a hash table (or binary tree, if you wish) from states to whatever code you want to execute: (Java 8)
HashMap<State, Function<State, State> stateTransitions;
This system provides enum-like semantics at runtime, with reasonably good (constant time "switch") efficiency.

Related

How to set cardinalities in Java field?

Let us suppose we have the following class:
public class MyClass{
List<String> list;
void method() {
}
}
Each object of this class has a list of strings, but what if we want to set the cardinality? For example, I want to force this class to have at least 2 strings in that list.
Is there a general pattern to represent the cardinalities on fields?
You simply need to make sure that there are at least 2 elements in list, by some means. There is no standard or simple way of doing this.
This is known as an invariant of the class. It is your responsibility as the person who writes the class to ensure that this invariant is preserved at all times. In particular:
You need to document the invariant that there are at least 2 elements in the list.
You need to ensure that the list contains at least two elements by the time the constructor finishes. The instance should be "valid" (in the sense that its documented invariant are true) when the constructor finishes.
You need to ensure that all code within the class honors the invariant when it manipulates the list - you are allowed to temporarily make it invalid, but you must ensure that it is not possible to observe your instance in an invalid state.
In the single-threaded cases, this simply means that the invariant must be true once the public method returns (note that this includes if an exception occurs); but if your code is designed to be used in a multithreaded way, you must also ensure that no thread can ever see your instance in a state where the invariant is false (e.g. you may need synchronized blocks, or ensure that updates are atomic).
You need to ensure that subclasses of your class are unable to make the invariant false; or document clearly that it is the responsibility of people writing subclasses to ensure that the invariant remains true.
There is a great item in Effective Java 2nd Ed about this: "Design and document for inheritance or else prohibit it".
You need to ensure that nothing outside your class is able to access the reference to the list. For example, your code makes the list visible to other classes in the same package - any of these classes could call theInstance.list.clear(), and invalidate your invariant.
It's pretty hard to prevent this absolutely - for example, it could be possible for malicious actors to invalidate the invariant using reflection. You can prevent this, but it's a question of weighing the effort of identifying and blocking such methods vs the actual cost of the invariant becoming false (this strongly depends upon how this class is used).
By far the easiest way to enforce an invariant is on an immutable class. If it's not possible to change the observable state of an instance, it's not possible to invalidate the invariant. Then, all you need to worry about is a) making sure that the class is immutable; b) making sure that the invariant is true once the constructor returns. All of the other points above then simply fall away.
Is there a general pattern to represent the cardinalities on fields?
Obviously, you can represent the cardinalities using integer fields, either in the objects themselves, or at the meta level. But that's not much help if you cannot enforce them.
There is no general pattern for that. #Andy Turner's answer provides a good summary of the alternatives on enforcement of cardinalities. I just want to add a couple of points:
Attempting to enforce the cardinality constraints via static typing is unlikely to work. The Java type system is not rich enough to do this in a pleasant way1.
Construction of objects that have fields that have minimum cardinalities can be tricky, especially if there are potentially circularities involving those fields.
One way to deal with construction is to separate the lifecycle of the objects into a "construction" phase and a "completed" phase. During the construction phase, the constraints are relaxed, to allow the construction to be performed in stages. At some point, a "completed" switch is "flipped". At that point 1) the cardinality constraints are checked, and 2) the behavior of mutating operations is changed to prevent changes that would violate cardinality.
This can be implemented using public constructors and a public method to "flip the switch". Alternatively, you can implement this using the builder pattern; e.g.
make the constructors private
use alternative private means to side-step the cardinalities while building
check the cardinalities and flip the switch (it one is needed) in the build() method.
Another approach is to allow fields to be below cardinality, but only allow items to be added to the fields when they are in that state. In other words, this is the "flip the switch" approach without an explicit switch. The downside is that a client needs to test if the cardinality constraint is in force yet; i.e. the constraint is weak.
1 - In theory, you could implement a ListOfTwoOrMore interface, etcetera, but that would bring a raft of new problems.
One way to do that is use a different type for the field. Now it has type List<String> which is a collection that can contain 0 or more elements. You can change it to a type which represents a list that contains 2 or more elements.
You could use var-args in constructor.
public MyClass(String s1, String s2, String... rest){
}

What is the most appropriate type of variable to use when coding a game's location? Boolean/String/Some other? (java)

First post so I hope this is an appropriate type question for this site. If not I'd appreciate it if someone could direct me to a more appropriate place. I'm extremely new at programming. I did a bit in high school and have recently decided to relearn starting with making a text-based survival game in Java7 using Eclipse.
Right now I'm coding the location superclass. The particular function I need help with is this: it needs to be able to keep track of which of 9 regions the user currently "is in" (which is then used in a large number of other classes for many various purposes. The location class also includes functionality for accepting user input to move to a new region, among various other things.) The way I started this was by making a boolean variable for each region and whenever a transition should occur that variable is set to true. But now I'm wondering if this is the most efficient way to do this. I have to take String inputs, run a method to standardize various acceptable answers into one, and then run it through a switch statement that makes the corresponding boolean variable true?
Would it be simpler to simply keep track of the location with a single String variable that gets set as whatever region the player is in? Or would that be more likely to cause errors or complications when coding? Would an array better suit this need? edit: (I just want to thank you guys for people such an open and helpful community. Its really appreciated.)
BIG EDIT: I wanted to further elaborate on what the regions will eventually do. In each region there will eventually be a handful of places the user can go to that are generic with a small number of places unique to each location. Other major superclasses would be altered depending on what region the user is in (example: my "encounters" superclass would have variables that dictate how likely certain encounters are to happen (i.e. chance to a hostile attack) and these variables would be altered depending on the region) but also by other instances (The "Time" superclass would keep track of the day and time of day which would also effect the variables in "encounters".) The current plan was to make a class for each generic place (i.e. Walmart, technology store, grocery, public park, etc.) They would contain different properties depending on the region and would also effect classes like "encounters". I was going to have their properties defined by if/else & switch statements depending on what region the user was in. But now I'm realizing it would make more sense to define their properties when I create the object.
While a lot of people are steering me to enums, some are also suggesting I make classes for each region, (and I am also hearing about interfaces.) If I were to go with the 2nd route I have 3 questions: (a) If the region classes were all subclasses to "Location", then wouldn't I have a problem creating objects for all the generic places inside the region classes (i.e. Walmarts) because the Walmart class can only belong to one superclass? (If not what is the difference between an object being created in a class and the actual relationship between a superclass and its subclasses) (b) If I initialized each region as an object instead of simply recording it with a variable, how would I achieve the original task of remembering which region the user is in (for functions as simple as printing the region out to making alterations to variables in classes like "encounters"). Wouldn't I still need to have some sort of variable to identify the region? And if so, that what practical purpose does creating classes for the region accomplish? (I can see this might still let me make the code cleaner by housing the variables that interact with "encounters" instead of having to use if/else/switch statements inside the "encounters" class (also in this case how could I make the variables in the region classes interact with the variables in "encounters" since neither belong to each other) but anything else?) (c) Would it make more sense to create classes for every region or a single region class that gets defined differently when initialized and WHY?
Finally, I know I may have asked too many questions but could someone please explain to me the different utilities found in enums and interfaces (I'm especially interested in hearing about enums) and now that you know a little bit more, should I be using enums, interfaces, or some sort of classes for the regions? Thank you guys so much!
Enum is very recommended, as stated by Vasily Liaskovsky.
Using int is a great way as well. For example:
int currentRegion;
static final int region1 = 0;
static final int region2 = 1;
static final int region3 = 2;
etc...
Make sure the region1 etc are stated final, so their IDs cannot be changed afterwards, static reference could save memory if you're using multiple location superclass objects, also easier accessible outside the class.
This way to check if you're in a certain region, just use a if statement:
if(currentRegion == region1) {}
To set it:
currentRegion = region1;
Simple as that
I disagree with the usage of an enum here. An enum is great, but not extendable. What if you want to add another region?
So just create classes, and pass them around. They might hold some form of string as identifier (but you should load the proper name from a file that can be localized, anyways).
With a proper class, you can easily add new transitions betwen regions (make your region class a graph) and much more.
Region current = ...;
List<Transition> neighbours = current.getNeighbours();
foreach (Transition t : neighbours)
System.out.println("To the " + transition.getDirection() + " is the " + transition.getTargetName());
// prints e.g. "To the north is the shadowy jungle"
There are a lot of ways todo this, and in an OOP language, you should really try to get into the mindset of using objects instead of setting integer flags or else.
Take a look on enum.
If the list of 9 regions should not grow as game develops, you can describe each of them in hardcoded fashion also utilizing power of objects. Enums can have custom properties and methods weawing them into your architecture, and also enums provide some extra benefits such as == comparison and using in switch blocks.
EDIT
I don't understand why this future addition might make enums a less desirable route
The only way to add an option to enum is to rewrite its class source code. That is, enum options are defined statically and in larger projects when developers should deal with product versions, compatibility, delivering to end-users etc., this could be a pain. In fact, any change in source code of published project is undesirable, since it requires recompilation and full rebuild of at least one (in best case) application module.
The way to deal with it is to move modifiable data into some resource (this can be a file, database table, plugin or anything easily modifiable without full rebuild) and make your application to initialize itself on startup in runtime. Since from this point your program no longer knows that data in advance, statically, there is no way you could define enum describing that data. And in this scenario custom classes (Polygnome's answer) will do the job. Your program reads the resource, creates and initializes objects in runtime that describe your configuration and uses dynamic data.
IMHO, there is almost always tradeoff beween flexibility and complexity. You gain flexibility and freedom to modify region list, but you have to deal with complexity of dynamic solution. Or you decide to use much simpler enums understanding their limited extensibility.
Btw, in order of growing flexibility (and complexity):
raw primitives (int/String) | enums | custom classes

Passing many variables to a class (swing components) [duplicate]

I have just started to learn Java and is curious is it any good practice in Java for good object decomposition? Let me describe a problem. In big software project it's always a big classes like 'core' or 'ui' that tends to have a lot of methods and are intended as a mediators between smaller classes. For example, if user clicks a button on some window, this window's class sends a message to 'ui' class. This 'ui' class catches this message and acts accordingly by doing something with application user interface ( via calling method of one of it's member objects ) or by posting message to application 'core' if it's something like 'exit application' or 'start network connection'.
Such objects is very hard to break apart since they are a mere mediators between a lots of small application objects. But having a classes in application with hundreds and thousands of methods is not very handy, event if such methods are trivial task delegation from one object to another. C# solves such problem by allowing to break class implementation into multiple source files: you can divide god object any way you choose, and it will work.
Any practices by dividing such objects in Java?
One way to begin breaking such a large object apart is to first find a good subset of fields or properties managed by the large object that are related to each other and that don't interact with other fields or properties of the object. Then, create a new, smaller object using only those fields. That is, move all logic from the large class to the new smaller class. In the original large class, create a delegation method that simply passes the request along. This is a good first step that only involves changing the big object. It doesn't reduce the number of methods, but it can greatly reduce the amount of logic needed in the large class.
After a few rounds of doing this, you can begin to remove some of the delegation by pointing other objects directly at the newer, smaller objects, rather than going through the previously-huge object that was in the middle of everything.
See Wikipedia's Delegation pattern discussion for example.
As a simple example, if you have a personnel object to represent staff at a company, then you could create a payroll object to keep track of payroll-related values, a ratings object to keep track of employee ratings, an awards object to keep track of awards that the person has won, and so on.
To wit, if you started out with one big class containing the following methods, each containing business logic, among many other methods:
...
public boolean isManagement() { ... }
public boolean isExecutive() { ... }
public int getYearsOfService() { ... }
public Date getHireDate() { ... }
public int getDepartment() { ... }
public BigDecimal getBasePay() { ... }
public BigDecimal getStockShares() { ... }
public boolean hasStockSharePlan() { ... }
...
then this big object could, in its constructor, create a newly created object StaffType and a newly created object PayInformation and a newly created object StaffInformation, and initially these methods in the big object would look like:
// Newly added variables, initialized in the constructor (or as appropriate)
private final StaffType staffType;
private final StaffInformation staffInformation;
private final PayInformation payInformation;
...
public boolean isManagement() { return staffType.isManagement(); }
public boolean isExecutive() { return staffType.isExecutive(); }
public int getYearsOfService() { return staffInformation.getYearsOfService(); }
public Date getHireDate() { return staffInformation.getHireDate(); }
public int getDepartment() { return staffInformation.getDepartment(); }
public BigDecimal getBasePay() { return payInformation.getBasePay(); }
public BigDecimal getStockShares() { return payInformation.getStockShares(); }
public boolean hasStockSharePlan() { return payInformation.hasStockSharePlan(); }
...
where the full logic that used to be in the big object has been moved to these three new smaller objects. With this change, you can break the big object into smaller parts without having to touch anything that makes use of the big object. However, as you do this over time, you'll find that some clients of the big object may only need access to one of the divisible components. For these clients, instead of them using the big object and delegating to the specific object, they can make direct use of the small object. But even if this refactoring never occurs, you've improved things by separating the business logic of unrelated items into different classes.
The next logical step may be to change the BigClass into a java package. Next create new objects for each group of related functionality (noting in each class that the object is part of the new package).
The benefits of doing this are dependency reduction and performance.
No need to import the entire
package/BigClass just to get a few
methods.
Code changes to related
functionality don't require a
recompile/redeploy of the entire
package/BigClass.
Less memory used
for allocating/deallocating objects,
since you are using smaller classes.
I've seen some cases where this is solved by inheritance: let's say class Big takes care of 5 different things, and (for various reasons) they all have to be in the same class. So you pick an arbitrary inheritance order, and define:
BigPart1 // all methods dealing with topic #1
BigPart2 extends BigPart1 // all methods dealing with topic #2
...
Big extends BigPart4 // all methods dealing with the last topic.
If you can really layer things up, so that the breakage makes sense (Part2 actually uses stuff from Part1, but not vice versa, etc.) then maybe it makes some sense.
The place where I've seen this is in WebWorks, where a single class had tons of getter/setter methods -- the setters used for dependency injection (e.g., URL args passed to the object upon execution) and the getters for making values accessible to various page templates (I think it was JSPs).
So, the breakdown grouped stuff logically, e.g., assuming the class was called MyAction, there was MyActionBasicArgs (fields and setters for basic CGI arguments), extended by MyActionAdvancedArgs (advanced-option args), extended by MyActionExposedValues (getters), extended by MyActionDependencies (setters used by Spring dependency injection, non-CGI args), extended by MyAction (which contained the actual execute() method).
Because of the way dependency injection in WebWorks works (or at least, used to work, back then), it had to be one huge class, so breaking it down this way made things more maintainable. But first, please, please, see if you can simply avoid having a single huge class; think carefully about your design.
Yes, C# provides partial classes. I assume this is what you are referring to when you say:
C# solves such problem by allowing to break class implementation into multiple source
files: you can divide god object any way you choose, and it will work.
This does help make huge classes more manageable. However, I find partial classes best used when one needs to extend code created by a code generator. When a class is as large as you're talking about, it can almost always be divided into smaller classes by proper object oriented design. Using a partial class sidesteps the more correct object oriented design, which is sometimes OK as the end goal is stable, reliable, maintainable code, and not a textbook example of OO code. However, many times, putting the code of a large object into a large number of smaller partial class instances of the same class is not the ideal solution.
If you can possibly find subsets of the properties of the "god" object that do not interact with one another, then each one of those sets would logically make a good candidate for a new object type. However, if all properties of this "god" object depend on one another, then there is not much you can do to decompose the object.
I don't know why you would ever have such a large class.
I suppose if you were using a gui builder code generation and being lazy about it, you might end up in such a situation, but codegen usually ends up nasty unless you take control yourself.
Splitting a single class arbitrarily is a terrible solution to a terrible manufactured problem. (Code reuse, for one thing will become virtually impossible)
If you have to use a GUI builder, have it build smaller components, then use the small components to build up a bigger GUI. Each component should do exactly one job and do it well.
Try not to EVER edit generated code if you can avoid it. Putting business logic into a genned "frame" is just a horrid design pattern. Most code generators aren't very helpful with this, so try to just make a single, minimal edit to get at what you need from external classes (think MVC where the genned code is your View and the code you edit should be in your Model and Controller).
Sometimes you can just expose the getComponents method from the Frame object, get all the components out by iterating through the containers and then dynamically bind them to data and code (often binding to the name property works well), I've been able to safely use form editors this way, and all the binding code tends to be very easily abstracted and reused.
If you're not talking about generated code--Well in your "God" class, does it do exactly one small job and do it well? If not, pull out a "Job", put it in it's own class, and delegate to it.
Is your GOD class fully factored? When I've seen huge classes like this, I've usually seen a lot of copy/paste/edit lines. If there is enough of a similarity to copy and past and edit some section, then there is enough to factor these lines into a single chunk of code.
If your big class is a GUI class, consider decorators--reusable and moves stuff out of your main class. A double win.
I guess the answer to your question is that in Java we just use good OO to ensure that the problem doesn't arise in the first place (or we don't--Java's certainly not immune to the problems you are talking about any more than any other language)

Why is making variables public visibility a bad practice

I am in a Introduction to Java class and I was doing a bit of research on variables. It seems that knowledgeable programers state that it is bad practice to define the variables in public visibility. I see them stating it is bad practice but I can not find a rhyme or reason to their claims. This is how I defined my variables in a application for my course.
public class DykhoffWk3Calculator
{
/*
* This class is used to define the variables in a static form so all
* classes can access them.
*/
public static double commissionRate = .03, startSalary = 45000,
accelerationFactor = 1.25;
public static double annualSales, commissionTotal, totalCompensation,
total, count, count2;
private static Object input; Object keyboard;
public static class UserInput
{ //Then continue with my other classes
I thought this was a logical method of defining them so all classes, not just main, could access them. Can someone explain to me why this is bad practice, and where variables should be defined? Any assistance would be greatly appreciated.
In short: because all of your public "surface area" for a class effectively defines its API.
If you expose things through methods, then you can change the details of how they work later. But if you expose a field, and some other class outside of your control (and quite possibly outside of your knowledge) starts referencing that field, then you're stuck with exposing that field for the rest of time. Or until you decide to break backwards-compatibility.
I thought this was a logical method of defining them so all classes, not just main, could access them.
As a general rule, you don't want "all classes" to access them. The vast majority of work with software, is spent maintaining code, not writing it for the first time. And so experienced developers realise that best practices for code, are generally the ones that make it most maintainable, not necessarily the ones that make it most convenient to write in the first place.
And if you have a variable that could be accessed from anywhere, at any time, and you want to make some tweaks to how it is modified - how can you be sure that this is safe? How long will it take you to track down all the ways that this is referenced, and determine what the effects of your change will be? (And specific to public fields, you can kiss goodbye to any sort of reusability regarding running at the same time from multiple threads, or running reentrantly.)
Broadly speaking, reducing the "surface area" of classes is a really good thing to do. Restricting the ways that other classes can interact with this one, makes it much easier to control and understand the relationships, as well as making it easier to make internal changes "invisible" to those other classes. Think about what this class does, what it will provide to other classes, as defining an interface (whether an actual interface or not). And only expose to other classes, the bare minimum that is required to fulfil those requirements.
And that never involves letting them have arbitrary access to variables.
So the general point is that you in fact DON'T want anyone to be able to access those values. Not only can I see those variables, but I can also change them to anything I like. This can lead to problems in larger, more complex programs.
Furthermore, if you wanted to later change how the class uses/stores these values, you couldn't without having to go out and change all the other classes that access those public variables directly. Instead, you should offer methods that provide just the amount of access that you want to give.
The standard analogy is that of driving a car. You know how to turn the wheel, hit the brake, etc, but not how the car actually does these things. So if the engine needed to be dramatically changed, or you got in a new car, then you'd still know how to drive. You don't need to worry about what's happening behind the scenes.
Firstly you state it wrong.
its bad to make your variable public i.e:
public String name = null; this is bad. You should always do it as
private String name = null;
To understand why, you need to dig a bit into the ideology of OOPs
OPPS ideology states that each object of your class will have 2 things:
Properties: something which we also call variables or state.
Behavior: something which we call methods or functions.
Properties identify the object over a period of time. Behaviors allow you to manage the properties of the object so that the same object over time can appear to be in different states.e.g: a Product object over a period of can be an 'Available line item' or 'Added to cart' or 'Sold' or 'Out of stock' depending on its state. Since state is critically important to the object so the object should not allow direct nonsense mutation operations on its state. Objects should keep their variables private to them and expose behaviors that the outside world can use to interact with the object and change the state based on the operation executed in the behavior. e.g: calling the 'addToCart()' behavior on the Product object that was in 'Available line item' state would probably mean: changing not just its state to 'Added to cart' but probably making other users aware that the number of this Products now available is 1 less.
So long story short: don't expose properties directly to outside work for mutation unless needed. This means dont make them public and also dont give setter methods if not needed.
By Convention Fields, methods and constructors declared public (least restrictive) within a public class are visible to any class in the Java program, whether these classes are in the same package or in another package.Which means that a change in the value of a field will definitely affect other classes accessing that field..thus breaking the whole sense of encapsulation.
Public variables in general in a class are a bad idea. Since this means other classes/programs, can modify the state of instances.
Since it is the responsibility of a class to protect its state and ensure the state is "consistent", one can enforce this by defining public setters (since this allows to run code to check/repair state).
By setting the variables public, the state is not protected. If later not all representable states are valid states, one has a problem.
Example:
Say you want to implement an ArrayList<T>, then it will look like (not fully implemented):
public class ArrayList<T> {
public int size = 0;
public Object[] data = new Object[5];
}
Now one can modify the size of the arrayList. Without adding an element. Now if you would ask the ArrayList<T> instance to remove/add/copy/...whatever, the data on which it works can be wrong.
Perhaps you can claim that a programmer is nice: he will not modify the object unless he needs to and according to the "rules". But such things eventually always go wrong, and what if you decide to modify your definition of the ArrayList (for instance using two int's for the size). In that case you would need to rewrite all code that sets such fields.
To conclude: private/protected is invented to protect a class instance from other instances that would turn the instance corrupt/invalid/inconsistent/...

Should enum objects be stateless?

As by design an enum constant in java is a singleton, and for sake of concurrent usage I normally create stateless enum instances and use method parameters to inject the data as needed.
Example:
Currently I am creating a REST service which has Operations (implemented as an enum using a variant of the strategy pattern).
public enum Operation {
DO_THIS() {
public Result doSomething(Object theData) {
}
} ,
// Other Operations go here
;
public abstract Result doSomething(Object theData);
}
Now I want to collect data about how often an operation has been called and how often it succeeded and the like.
I could save the state externally when using the enum instance but it rather seems that the state should be saved in the Operation as the operation should contain it's own state.
Now my general question is:
Is a stateful enum instance (besides from concurrency issues) a bad design?
I think it violates the Principle of Least Astonishment.
People expect the common usage of enums as they were originally designed - as constants or tokens, and not as general purpose classes with state.
Yes. And by 'yes' I mean 'Always'.
If you want to collate stats on the number of operations called, implement some observability.
Any form of mutable static is a sin. (Well, you might get away with non-leaky caches, some lazy initialisation and forms of logging.)
A stateful enumeration is an oxymoron, even an anti-pattern!
http://en.wikipedia.org/wiki/Enumeration
An enumeration is a collection of items that is a complete, ordered listing of all of the items in that collection. The term is commonly used in mathematics and theoretical computer science to refer to a listing of all of the elements of a set. In statistics the term categorical variable is used rather than enumeration. The precise requirements for an enumeration (for example, whether the set must be finite, or whether the list is allowed to contain repetitions) depend on the branch of mathematics and the context in which one is working.
Enumerations have a finite number of values, which are supposed to be constant, which they are.
However, the fact that they are "first class" Java Objects totally goes against the grain of the intention or spirit of an enumeration.
If any kind of state is required, the enum (as mentioned earlier) should hold state in an Aspect or the offending enum, should at the very practical least, hold a reference to a delegate class holding state. Understanding "separation of concerns" will help.
This seems like a bad use for enums - why not just go with a base abstract class with a new subclass for each operation?
I entirely agree with mparaz that it violates the Principle of Least Astonishment. People expect enums to be constants.
You can almost certainly work round the logging thing, by something like:
DO_THIS() {
public Result doSomething(Object theData) {
MyUtilClass.doSomething(Object theData);
}
}
and put your logging in the other class.
HOWEVER if you can't work round this, the Principle of Least Astonishment is a guideline; you can violate it PROVIDED you give users of the class enough warnings about what is going on. Make sure the Enum declaration contains a BIG notice saying that it is mutable, and describing exactly what the mutability is. The Enum should still work; it's doing reference comparison against to single instance to test enum values.
There is a case which would probably justify it.
An enum can implement an interface, usually with the particular use case in mind which lets you create
on runtime/openly "some other types of the enum class" in a dynamic fashion, to name it someway.
That means that enum "singleton" instances can be forced to implement some mutable-intended method signatures (as setters), which of course, you still can hide with an empty code or a NotSupportedException.
Luckily, final methods in an interface don't allow any possibility to change state. That would have been the sole "understandable" case I could come up with.

Categories