I found out that I can assign data to a property using set or a method.
class Human {
String name, address;
set rewriteName(String name) {
this.name = name;
}
set rewriteAddress(String address) {
this.address = address;
}
void rewrite(String name, String address) {
this.name = name;
this.address = address;
}
String introduction() => "Name is $name. I live in $address";
Human(this.name, this.address);
}
I tried to assign some data using both way, and method looks more efficient than using setter, since its only need just one call to change everything:
Human human = Human('stacker', 'baghdad');
// using method
human.rewrite('overflow', 'new york');
// using setter
human.rewriteName = "Hooman";
human.rewriteAddress = "jakarta";
my question is why using a setter instead of method?
CodePudding user response:
It's basically about what the usage looks like, a method call with a parameter vs. what looks like an assignment to a property. From Dart.dev's Effective Dart: Design
DO use setters for operations that conceptually change properties.
Linter rule:
use_setters_to_change_properties
Deciding between a setter versus a method is similar to deciding between a getter versus a method. In both cases, the operation should be “field-like”.
For a setter, “field-like” means:
The operation takes a single argument and does not produce a result value.
The operation changes some state in the object.
The operation is idempotent. Calling the same setter twice with the same value should do nothing the second time as far as the caller is concerned. Internally, maybe you’ve got some cache invalidation or logging going on. That’s fine. But from the caller’s perspective, it appears that the second call does nothing.
In your example you're comparing a method that changes two properties with two separate setters. You'd use the method if it's essential that the two properties both be updated at the same time, as a single conceptual operation. If the properties are independent (and otherwise meet the criteria above), you might use setters instead (if you need to do something when they're set; otherwise, simple data fields might make more sense).
CodePudding user response:
Typically, the targets of getters and setters are made private so they're not directly accessible from outside of the file or library.
class Human {
String name, _address;
Map propertyRecords = {};
get address {
return _address;
}
set address(String address) {
_address = address;
// do some API call to set property records.
// or some other complex thing that doesn't change, like lat/long
}
void rewrite(String name, String address) {
this.name = name;
this.address = address;
}
String introduction() => "Name is $name. I live in $address";
Human(this.name, this.address);
}
The user of the class feels like they're using a normal variable, but it does other silent things.
Methods can do this too, yes, but this can feel cleaner.
Importantly, getters and setters cannot be asynchronous which definitely can give methods an advantage, but there are plenty of valid uses.
Getters and setters are also easier to read, when being used. Less parentheses are always a good thing.
You certainly don't need to always use them, or use them when they do nothing but set the variable, but they can be nice.
In one of my Widgets, I have a getter that looks something like
FileState get fileState => FileUploaderKey.currentState!. widget.file.state;
It's so much easier to read this way. It gets the current state of the file, always, whereas
FileState fileState = FileUploaderKey.currentState!.widget.file.state;
Only saves the current state, but doesn't change with it.