A Class
isn't truly immutable if any of this children references aren't immutable as well.
If your root Class
has final
references to all its instance variables and all those instance variables are immutable as well as all their children following this same restriction then you can say the root Class
is immutable.
If any of the children references are non-final
or any of the children instances are mutable then the containing Class
is not immutable.
It doesn't matter about the internal immutablity whatever that means is anyone's guess, all that matters is that the public contract to the class immutability is kept. You can't have partial immutability anymore than you can be partially dead. Your class is either immutable or it isn't. And it isn't if any of its referred to classes or their classes, etc. are mutable.
If you have a graph and any of the members of the graph are mutable you can't deterministically say that you have an immutable state. Concurrency guarantees go out the window, .equals()
and .hashCode()
become non-deterministic and simple to test cloning and serializing go out the window as well.
If anything breaks this immutability contract you lose all the benefits of trying to maintain this immutability contract.
Simpler concurrency issues is a main motivational force of immutability.
Having side effect free code helps with predictability and maintainability. Since you don't have to wonder where things are getting mutated in the call tree because you know they can't be mutated.
Performance is another less important factor, in Java the JVM can make some highly optimized decisions about caching and other factors if it knows data can't change state. It does provide important hints to the compiler at compile time and the JIT algorithms at runtime.
In a complex routing system, generally a controller should be looked up by a name that is based on what its job is or what route it handles. When your app "boots up" you register controllers under those names so that the class name isn't hard coded everywhere, allowing you to swap out controllers easily. This is what the App
facade in Laravel does.
There is nothing wrong with using static classes (abstracts with final private constructors) in place of singletons (I personally think they are preferable to singletons), and if you know your core won't grow too much then this is fine. The drawback is if you ever want to switch to the more dynamic way of doing it you're going to have to refactor.
An ideal MVC is thin. As Laravel's creator Taylor Otwell put it, be careful not to box yourself in to a "pure MVC" paradigm. A web service consists of more than MVC; MVC is just a pattern, not an architecture.
Best Answer
If you are making an immutable DTO, where you simply bundle up a bunch of properties and that's it, such as your example, then just use a public constructor.
Factories are for situations where object construction is complicated, expensive, where you return different types based on the input values, or other "logic intensive" situations. Simply storing a handful of values is not one of those situations.