Why should I avoid wrapping fields in getters and setters? - flutter

I am building a Flutter app. I have a class that looks like this:
class ToDo {
String _title;
bool _done;
String get title => _title;
void set title(String newTitle) { _title = newTitle; }
bool get _done => _done
void set done(bool done) { _done = done; }
}
But the Dart linter is complaining that I should "Avoid wrapping fields in getters and setters just to be safe". However, this doesn't make much sense to me. Right now the getters are useless, but what if in the future I need to do some kind of processing before accessing a variable from outside? All I'll have to do is update the getters. However, if the properties were public and being accessed directly, I would have to update the whole codebase if some business rule changed.
So what is the point of this warning? Or, in other words, why creating "useless getters" would be a bad practice?

However, if the properties were public and being accessed directly, I would have to update the whole codebase if some business rule changed.
Ask yourself this: what exactly would you need to change in your Dart codebase if you had to change a public member to use an explicit getter and setter instead?
In most languages, getters and setters look like method calls to consumers. If you wanted to replace a public data member with a public getter and setter, that would be a breaking API change, requiring changes to everything that uses it.
Dart is not like that. Getters and setters do not look like method calls to consumers; they are indistinguishable from direct member access. (Having a public data member implicitly declares a corresponding getter and setter as part of the class's interface.) Changing a public data member to a public getter and setter would not require any changes to callers, so providing trivial getters and setters around private member variables provides no benefit.
(This is also explained by the documentation for the unnecessary_getters_setters lint that you encountered.)
Incidentally, the unnecessary_getters_setters lint should occur only if you provide both a getter and a setter (which is not what your example code does). If you provide only one, then it would no longer be equivalent to a public data member.

Just to add to this I would like to make an additional comment. This error goes away if you do something else within the setter, not just set the value. In my use case I was setting a value in a Provider and was calling notifyListeners().
By adding this additional functionality the lint warning disappears. I guess because the setter is doing more than just setting the value.

Related

Why do state's class variable are often done as private in Flutter?

Why do state's class variable are often done as private? What are the cases when using public variables is bad for state classes? Who is going to use variable from state class like this: _SplashState.storage?
class _SplashState extends State<Splash> {
var_storage = Storage(); // it could be public
It's not necessary to create the State as private but it makes sense. The State class should be private indicating it should not be created anywhere outside createState override, as you are not creating/managing State object instance at all.
We can also say that it's good practice to declare a variable as private which is not to be accessed outside of the scrop.
Private fields have the advantage that Lint can identify which fields were declared or instantiated and not used, which helps identify human errors.
If you declare a public field, the field can be accessed by outside classes, so Lint cannot warn you if you added the field by mistake.

HTL Access Property Without Getter

I'm writing an AEM component and I have an object being returned that is a type from an SDK. This type has public properties and no getters. For simplicity, it might be defined like this:
class MyItem {
public String prop1;
public String prop2;
}
Now normally, I would need a getter, like so:
class MyItem {
public String prop1;
public String prop2;
public String getProp1() {
return prop1;
}
}
But I do not have this luxury. Right now, I've got a Java implementation that uses another type to resolve this, but I think it's sort of crazy that HTL doesn't allow me to just access prop1 directly (it calls the getter). I've reviewed the documentation and can't see any indication of how this could be done. I'd like to be able to write:
${item.prop1}
And have it access the public property instead of calling getProp1().
Is this possible?
You don't need getters for public fields if those fields were declared by your Java Use-class. There's actually a test in Apache Sling that covers this scenario:
https://github.com/apache/sling/blob/trunk/bundles/scripting/sightly/testing-content/src/main/resources/SLING-INF/apps/sightly/scripts/use/repopojo.html
This also applies to Use-classes exported from bundles.
For Sling Models using the adapter pattern [0] I've created https://issues.apache.org/jira/browse/SLING-7075.
[0] - https://sling.apache.org/documentation/bundles/models.html#specifying-an-alternate-adapter-class-since-110
From the official documentation
Once the use-class has initialized, the HTL file is run. During this stage HTL will typically pull in the state of various member variables of the use-class and render them for presentation.
To provide access to these values from within the HTL file you must define custom getter methods in the use-class according to the following naming convention:
A method of the form getXyz will expose within the HTL file an object property called xyz.
For example, in the following example, the methods getTitle and getDescription result in the object properties title and description becoming accessible within the context of the HTL file:
The HTL parser does enumerate all the public properties just like any java enumeration of public fuields which include getters and public memebers.
Although it is questionable on whether you should have public variable but thats not part of this discussion. In essence ot should work as pointed by others.

eclipse null analysis field initialization

Using the Null Analysis of Eclipse:
It it possible to define other methods as initializing methods than Constructors?
I have a class like this:
public class Foo {
#NonNull
private Object fooObject;
public Foo() {
super();
}
public void onCreate() {
fooObject = //Something which is not available in the Constructor;
}
Here i get the warning that the NonNull field may has not been initialized. Is there any possibility to kind of declare the init-method as an initalizing one?
I could use #SuppressWarnings("null") for the constructor. But then I ignore all fields, which may instanciated somewhere.
Second chance i see is to make fooObject as #Nullable - but then i need check for null each time i use fooObject.
So is there any better solution?
Null-checking object initialization beyond the constructor is inherently difficult. Several sophisticated approaches exist, all of which require additional annotations.
In your example it seems to be near-impossible, to prove to the compiler, that onCreate() is always called before accessing the field.
A weaker solution has been proposed: #LazyNonNull, an annotation to be used on fields that are initially null, but once initialized can never go back to null. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=414237
Obviously, a static factory method, that gathers all necessary values before invoking a constructor (with arguments) would be a lot easier to get right.

If I can't use datacontext in a static

I've got this
public static class MyClassHelper
{
DataContex db = new DataContext();
public static Type MyMethod()
{
//Do Something with db
// such as db.myTable
}
}
I'm getting the following error: "An object reference is required for the non-static field, method or property..."
Is there anyway to get around this?
How about this. I've an object that contains only integers, which is fine for all the internal functionings as it allows me to link tables. But occasionaly, I need to display some information to the user. That's why, I'd like to create a static method so it would read the integer, look up in the DB, and display a name instead of a number.
I want it to be a static method so that I can use it in my View template.
Thanks for helping
As #Oskar indicates your static method can't reference instance variables, only static variables. Rather than making the DataContext static, though, which would mean that it would exist for the life of the program, just create the DataContext as needed within the method. DataContext are best suited to a "unit of work" pattern and recreated as needed for just the task being accomplished rather than existing as a long-lived object. Be aware, too, that the DataContext is not thread-safe; you'll be creating some really hard to find errors unless you make all of your methods thread-safe. It's much simpler to just recreate the data context.
A static method can only see static members. Also, a static class can only have static member. You should mark your db as static:
static DataContext db = new DataContext();
Yep. You need to declare your DataContext to be static as well.

benefits of getter/setter VS public vars?

Is there a benifit to using:
private var _someProp:String;
public function set someProp(value:String):void
{
_someProp = value;
}
public function get someProp():String
{
return _someProp;
}
As opposed to just using:
public var someProp:String;
I realise using getter/setter can be useful when you need to further processing or need to be notified of when the property is changed like so:
public function set someProp(value:String):void
{
_someProp = value;
_somePropChanged = true;
doSomethingElse();
}
But if you don't need this, then is there any reason to use getter/setter over just using a public var?
Thanks!!
Depending on your language, you should prefer getter/setter up front because you can't introduce them later (I'm looking at you, Java) if it turns out you do need them.
This really depends a bit on the language/framework/toolkit you are using -
However, there are often benefits when using getters and setters related to versioning and API compatibility. This can be a very useful reason to use them, all on its own.
This really can't be answered without knowing the language. Getters and Setters cost more in most languages, but they buy you flexibility down the road. In some languages you can't change a public to a Getter/Setter without changing the code in the callers because the use syntax changes. But this is not an issue with C#, which I what I write in mostly.
Getters and Setters let you do parameter validation. They let you delay creation of objects until first reference. They have a lot of advantages, and I use them whenever I need one of those advantages from the beginning.
But I use getters and setters ONLY when I need them right away, or when I'm pretty sure I'm going to need the flexibility. Otherwise I view them as bloat.
As a side note, you can start with a public var and if necessary convert it to a getter / setter later in code.. depending on the language you are using.
If your property is totally dumb, and has no side effects on the rest of the class - then by all means just expose it as a public field.
Its just that in many cases your properties will have side effects, so you need to control how they are set and accessed.
As a trivial example, what happens if your public variable is not set to something in your constructor? Are you ok with this being returned as null? Or would you like to set this variable to something rather than return null? This is a simple example where a custom getter is worthwhile.
Getters and Setters also give you more control over what values the variable can be set to.
bool setAge(int age){
bol retVal = true;
if(age <= 0)
retVal = false;
return retVal;
}
Without the setter, the value could be set to zero and bad things could happen.