benefits of getter/setter VS public vars? - setter

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.

Related

Why should I avoid wrapping fields in getters and setters?

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.

Make long names shorter in Unity?

Instead of writing a code like
FindObjectOfType<GameManager>().gameOver()
I would like to type just
gm.gameOver()
Is there a way to do that in Unity?
Maybe using some kind of alias, or some kind of namespace or something else. I am after making my code clean, so using GameManger gm = FindObjectOfType() in every file that uses a the GameManager is not what I am looking for.
In general I have to discourage this question. This is very questionable and I would actually not recommend this kind of shortening aliases for types and especially not for a complete method call ... bad enough when it is done with variables and fields by a lot of people.
Always use proper variable and field names thus that by reading the code you already know what you are dealing with!
how about storing it in a variable (or class field) at the beginning or whenever needed (but as early as possible)
// You could also reference it already in the Inspector
// and skip the FindObjectOfType call entirely
[SerializeField] private _GameManager gm;
private void Awake()
{
if(!gm) gm = FindObjectOfType<_GameManager>();
}
and then later use
gm.gameOver();
where needed.
In general you should do this only once because FindObjectOfType is a very performance intense call.
This has to be done of course for each class wanting to use the _GameManager instance ...
However this would mostly be the preferred way to go.
Alternatively you could also (ab)use a Singleton pattern ... it is controversial and a lot of people hate it kind of ... but actually in the end FindObjectOfType on the design side does kind of the same thing and is even worse in performance ...
public class _GameManager : MonoBehaviour
{
// Backing field where the instance reference will actually be stored
private static _GameManager instance;
// A public read-only property for either returning the existing reference
// finding it in the scene
// or creating one if not existing at all
public static _GameManager Instance
{
get
{
// if the reference exists already simply return it
if(instance) return instance;
// otherwise find it in the scene
instance = FindObjectOfType<_GameManager>();
// if found return it now
if(instance) return instance;
// otherwise a lazy creation of the object if not existing in scene
instance = new GameObject("_GameManager").AddComponent<_GameManager>();
return instance;
}
}
private void Awake()
{
instance = this;
}
}
so you can at least reduce it to
_GameManager.Instance.gameOver();
the only alias you can create now would be using a using statement at the top of the file like e.g.
using gm = _GameManager;
then you can use
gm.Instance.gameOver();
it probably won't get much shorter then this.
But as said this is very questionable and doesn't bring any real benefit, it only makes your code worse to read/maintain! What if later in time you also have a GridManager and a GroupMaster? Then calling something gm is only confusing ;)
Btw you shouldn't start types with a _ .. rather call it e.g. MyGameManager or use a different namespace if you wanted to avoid name conflicts with an existing type

What is the point declaring variables at the end of class?

I saw multiple examples in MSDN that uses to declare the internal fields at the end of the class. What is the point?
I find this a little embarrassing, because each time Visual Studio adds a method it adds it to the end of the class, so there is need every time to move it...
class A
{
public A(){}
// Methods, Properties, etc ...
private string name;
}
class A
{
private string name;
public A(){}
// Methods, Properties, etc ...
}
In C++, it makes sense to put the public interface of the class at the top, so that any user of the class can open up your header file and quickly see what's available. By implication, protected and private members are put at the bottom.
In C# and Java, where interface and implementation are completely intertwined, people would probably not open your class's source code to see what's available. Instead they would rely on code completion or generated documentation. In that case, the ordering of the class members is irrelevant.
If it's obvious the variable has been declared, and the code is by way of an example, then arguably this gets you to the bit being demonstrated quicker - that's all I can think of.
Add-ins like ReSharper will allow you to standardise and automatically apply this layout at the touch of a key combination, by the way, if it is what you want.
Many programmers strive for self-documenting code that helps clients to understand it. In C++ class declaration, they would go from most important (i.e. what is probably most frequently inspected) to least important:
class Class {
public:
// First what interest all clients.
static Class FromFoobar(float foobar); // Named constructors in client code
// often document best
Class(); // "Unnamed" constructors.
/* public methods */
protected:
// This is only of interest to those who specialize
// your class.
private:
// Of interest to your class.
};
Building on that, if you use Qt, the following ordering might be interesting:
class SomeQtClass : public QObject {
public:
signals: // what clients can couple on
public slots: // what clients can couple to
protected:
protected slots:
};
Then the same down for protected and private slots. There is no specific reason why I prefer signals over slots; maybe because signals are always public, but I guess the ordering of them would depend on the situation, anyhow, I keep it consistent.
Another bit I like is to use the access-specifiers to visually seperate behaviour from data (following the importance ordering, behaviour first, data last, because behaviour is the top-interest for the class implementor):
class Class {
private:
void foobar() ;
private:
float frob_;
int glob_;
};
Keeping the last rule helps to prevent visual scattering of class components (we all know how some legacy classes look like over time, when variables and functions are mixed up, not?).
I don't think there is any valid reason for this. If you run Code Analysis on a class declared like this you'll get an error as private fields should be declared on top of classes (and below constants).

Class design: file conversion logic and class design

This is pretty basic, but sort of a generic issue so I want to hear what people's thoughts are. I have a situation where I need to take an existing MSI file and update it with a few standard modifications and spit out a new MSI file (duplication of old file with changes).
I started writing this with a few public methods and a basic input path for the original MSI. The thing is, for this to work properly, a strict path of calls has to be followed from the caller:
var custom = CustomPackage(sourcemsipath);
custom.Duplicate(targetmsipath);
custom.Upgrade();
custom.Save();
custom.WriteSmsXmlFile(targetxmlpath);
Would it be better to put all the conversion logic as part of the constructor instead of making them available as public methods? (in order to avoid having the caller have to know what the "proper order" is):
var custom = CustomPackage(sourcemsipath, targetmsipath); // saves converted msi
custom.WriteSmsXmlFile(targetxmlpath); // saves optional xml for sms
The constructor would then directly duplicate the MSI file, upgrade it and save it to the target location. The "WriteSmsXmlFile is still a public method since it is not always required.
Personally I don't like to have the constructor actually "do stuff" - I prefer to be able to call public methods, but it seems wrong to assume that the caller should know the proper order of calls?
An alternative would be to duplicate the file first, and then pass the duplicated file to the constructor - but it seems better to have the class do this on its own.
Maybe I got it all backwards and need two classes instead: SourcePackage, TargetPackage and pass the SourcePackage into the constructor of the TargetPackage?
I'd go with your first thought: put all of the conversion logic into one place. No reason to expose that sequence to users.
Incidentally, I agree with you about not putting actions into a constructor. I'd probably not do this in the constructor, and instead do it in a separate converter method, but that's personal taste.
It may be just me, but the thought of a constructor doing all these things makes me shiver. But why not provide a static method, which does all this:
public class CustomPackage
{
private CustomPackage(String sourcePath)
{
...
}
public static CustomPackage Create(String sourcePath, String targetPath)
{
var custom = CustomPackage(sourcePath);
custom.Duplicate(targetPath);
custom.Upgrade();
custom.Save();
return custom;
}
}
The actual advantage of this method is, that you won't have to give out an instance of CustomPackage unless the conversion process actually succeeded (safe of the optional parts).
Edit In C#, this factory method can even be used (by using delegates) as a "true" factory according to the Factory Pattern:
public interface ICustomizedPackage
{
...
}
public class CustomPackage: ICustomizedPackage
{
...
}
public class Consumer
{
public delegate ICustomizedPackage Factory(String,String);
private Factory factory;
public Consumer(Factory factory)
{
this.factory = factory;
}
private ICustomizedPackage CreatePackage()
{
return factory.Invoke(..., ...);
}
...
}
and later:
new Consumer(CustomPackage.Create);
You're right to think that the constructor shouldn't do any more work than to simply initialize the object.
Sounds to me like what you need is a Convert(targetmsipath) function that wraps the calls to Duplicate, Upgrade and Save, thereby removing the need for the caller to know the correct order of operations, while at the same time keeping the logic out of the constructor.
You can also overload it to include a targetxmlpath parameter that, when supplied, also calls the WriteSmsXmlFile function. That way all the related operations are called from the same function on the caller's side and the order of operations is always correct.
In such situations I typicaly use the following design:
var task = new Task(src, dst); // required params goes to constructor
task.Progress = ProgressHandler; // optional params setup
task.Run();
I think there are service-oriented ways and object-oritented ways.
The service-oriented way would be to create series of filters that passes along an immutable data transfer object (entity).
var service1 = new Msi1Service();
var msi1 = service1.ReadFromFile(sourceMsiPath);
var service2 = new MsiCustomService();
var msi2 = service2.Convert(msi1);
service2.WriteToFile(msi2, targetMsiPath);
service2.WriteSmsXmlFile(msi2, targetXmlPath);
The object-oriented ways can use decorator pattern.
var decoratedMsi = new CustomMsiDecorator(new MsiFile(sourceMsiPath));
decoratedMsi.WriteToFile(targetMsiPath);
decoratedMsi.WriteSmsXmlFile(targetXmlPath);

Entity Framework: Cancel a property change if no change in value

When setting a property on an entity object, it is saving the value to the database even if the value is exactly the same as it was before. Is there anyway to prevent this?
Example:
If I load a Movie object and the Title is "A", if I set the Title to "A" again and SaveChanges() I was hoping that I wouldn't see the UPDATE statement in SqlProfiler but I am. Is there anyway to stop this?
Yes, you can change this. Doing so isn't trivial, however, in the current version of the Entity Framework. It will become easier in the future.
The reason you're seeing this behavior is because of the default code generation for the entity model. Here is a representative example:
public global::System.Guid Id
{
get
{
return this._Id;
}
set
{
// always!
this.OnIdChanging(value);
this.ReportPropertyChanging("Id");
this._Id = global::System.Data.Objects.DataClasses
.StructuralObject.SetValidValue(value);
this.ReportPropertyChanged("Id");
this.OnIdChanged();
}
}
private global::System.Guid _Id;
partial void OnIdChanging(global::System.Guid value);
partial void OnIdChanged();
This default code generation is reasonable, because the Entity Framework doesn't know the semantics of how you intend to use the values. The types in the property may or may not be comparable, and even if they are, the framework can't know how you intend to use reference equality versus value equality in all cases. For certain value types like decimal, it's pretty clear, but in a general sense it's not obvious.
You, on the other hand, know your code, and can customize this some. The trouble is that this is generated code, so you can't just go in and edit it. You need to either take over the code generation, or make it unnecessary. So let's look at the three options.
Take over the code generation
The essential approach here is to create a T4 template which does the code behind, and that the default code generation from the Entity Framework. Here is one example. One advantage of this approach is that the Entity Framework will be moving to T4 generation in the next version, so your template will probably work well in future versions.
Eliminate code generation
The second approach would be to eliminate cogeneration altogether, and do your change tracking support manually, via IPOCO. Instead of changing how the code is generated, with this approach you don't do any code generation at all, and instead provide change tracking support to the Entity Framework by implementing several interfaces. See the linked post for more detail.
Wait
Another option is to live with the Entity Framework the way it is for the time being, and wait until the next release to get the behavior you desire. The next version of the Entity Framework will use T4 by default, so customizing the code generation will be very easy.
According to MSDN:
The state of an object is changed from
Unchanged to Modified whenever a
property setter is called. This occurs
even when the value being set is the
same as the current value. After the
AcceptAllChanges method is called, the
state is returned to Unchanged. By
default, AcceptAllChanges is called
during the SaveChanges operation.
Looks like you'll want to check the value of properties on your Entity objects before you update to prevent the UPDATE statement.
At a generic level, if your entities are implementing INotifyPropertyChanged, you don't want the PropertyChanged event firing if the value is the same. So each property looks like this :-
public decimal Value
{
get
{
return _value;
}
set
{
if (_value != value)
{
_value = value;
if (_propertyChanged != null) _propertyChanged(this, new PropertyChangedEventArgs("Value"));
}
}
}
Hope that's relevant to Entity Framework.
One thing you can do is just wrap the property yourself using a partial class file, and then use your property instead of the first one:
public sealed partial class MyEFType {
public string MyWrappedProperty {
get {
return MyProperty;
}
set {
if (value == MyProperty)
return;
MyProperty = value;
}
}
}
It wouldn't be very practical to do this to every property, but if you have a need to detect that a particular property has actually changed and not just been written to, something like this could work.