Is defining get/set methods for every field overkill?

Andrey Zherikov andrey.zherikov at gmail.com
Sat Nov 19 09:07:39 UTC 2022


On Saturday, 19 November 2022 at 04:13:33 UTC, []() {}() wrote:
> oh. so i get it now. you have to refactor your class (change 
> member variable names and also do it in all places where they 
> are used througout the class. then add new methods, overloading 
> them in this way and that way, all because you're initial 
> design never factored in the possibility of change (or even 
> some validation of the vale being returned to the client, or 
> validation of value coming from the client).

You are not required to rename everything, just actual members.

D has nice feature to convert `foo.bar` to `foo.bar()` and 
`foo.bar = value` to `foo.bar(value)` that doesn't exist in C/C++ 
for example. This reduces some headache in planning the API ahead.

Let's we have this class and its usage:
```d
class Rect2D {
     int width;
     int height;

     auto area() const { return width * height; }
}

Rect2D rect = new Rect2D();
rect.width = 5;
rect.height = 5;

writeln(rect.area);   // note that this is seamlessly translated 
to rect.area()
```

Then you decided that you want getters/setters so you add them 
without changing anything:
```d
class Rect2D {
     int width_;
     int height_;

     auto width() const { return width_; }
     void width(int w) { width_ = w; }

     auto height() const { return height_; }
     void height(int h) { height_ = h; }

     auto area() const { return width * height; }   // no changes 
here - using getters
}

Rect2D rect = new Rect2D();
rect.width = 5;   // no changes here - using setter
rect.height = 5;  // no changes here - using setter

writeln(rect.area);
```

You can also use UFCS instead of class members but it has a 
caveat: plain `width`/`height` won't work within class so you 
have to either use `width_`/`height_` directly or 
`this.width`/`this.height`:
```d
class Rect2D {
     int width_;
     int height_;

     auto area() const { return this.width * this.height; }  // 
UFCS calls to global width() and height() functions
}

// These functions have to be in global scope for UFCS to work
auto width(const Rect2D rect) { return rect.width_; }
void width(ref Rect2D rect, int w) { rect.width_ = w; }

auto height(const Rect2D rect) { return rect.height_; }
void height(ref Rect2D rect, int h) { rect.height_ = h; }

void main()
{
     // Still no changes in user code
     Rect2D rect = new Rect2D();
     rect.width = 5;
     rect.height = 5;

     writeln(rect.area);
}
```


More information about the Digitalmars-d-learn mailing list