Private variables are Private
Tags: beginners, oop, codenewbie, typescript
Published: 2021-08-29 15:00:43

We see, quite lot of us comfortable with getters and setters in objects, for accessing private variables. 

But exposing a private variable with a getter or manipulate it with a setter, doesn't make any sense of why we made those variables private in the first place.

Instead we could have made them public, right ?

###Consider the difference between 1a and 1b,

Example 1a : `graph.ts`


```
class Graph {
    _x = 0;
    _y = 0;

    get x():number{
        return this._x;
    }

    get x():number{
        return  this._y;
    }

    set x(x:number){
        this._x = x;
    }

    set y(y:number){
        this._y = y;
    }
   
}
```


Example 1b : `graph.ts`

```
class Graph {
    getXYCoordinates(){
        // some code
    };

    setXYCoordinates(x: number, y:number){
        // some code
    };

    getXYZCoordinates(){
        // some code
    };

    setXYZCoordinates(x: number, y:number, z:number){
        // some code
    };
}
```


As we see, both 1a and 1b tries to set x,y points in a cartesian plane.

Yet,

1a `exposes` its implementation.
1b `hides` its implementation.

Both has the features of a `Data Structure`. While 1b is even more, an `Object`.

You can't say which type of graph 1b is, it may be a 3D graph or a 2D graph.

And this is what we know as `Abstraction`.

Which means 
`Hiding the implementation`
>A class is not something that gets and sets the data rather it manipulates only the essence of the data, without the need to know its implementation.

We can't simply add more and more getters inside a class like the following `journey.js`
```
class Journey {
    getSpeedRange(){
        // some code
        };

    getKMTravelled(){
        // some code
        };
    
    getTotalTime(){
        // some code
        };
}
```
If we do, then it is not hiding its implementation, rather its just exposes its variables through plenty of getters.

Rather we can,
```
class Journey {
    getAverageSpeedForTotalJourney(){
        // some code
        };
}
```

We must know a way to represent the data that an object contains.

>By hiding the implementation of the data and exposing only its behavior.

We make variables private so that we can hide their details to the outside World.

>In objects, data holders are hidden in the name of Abstraction and the functions that work on those data are exposed.

If we are trying to expose the data, then we are not working with objects here.

We call them `Data Structures`

As Data Structures and Objects are Anti-Symmetry.

Data Structures are opposite to that of Objects.

>In Data Structures, data holders are exposed and they have no meaningful functions to work on those data.

Lets see an example regarding Data Structures,

```
interface Square {
    side: number;
}

interface Rectangle{
    length: number;
    width: number;
}

interface Circle{
    radius: number;
}


class Geomentry {
    square: Square;
    rectangle: Rectangle;
    circle: Circle;

    constructor(square: Square, rectangle: Rectangle, circle: Circle){
        this.square = square; 
        this.rectangle = rectangle;
        this.circle = circle;
    }


    AreaOfSquare(): number{
        return this.square.side ** 2;
        }
    
    AreaOfRectangle(): number{
        return this.rectangle.length * this.rectangle.width;
        }
    AreaOfCircle(): number{
        const pi = 3.14285;
        return pi * this.circle.radius ** 2;
        }

}
const geomentry = new Geomentry({side: 6}, 
                                {length: 10, width: 5}, 
                                {radius: 6});

console.log("Area of Square", geomentry.AreaOfSquare());

console.log("Area of Rectangle", geomentry.AreaOfRectangle());

console.log("Area of circle", geomentry.AreaOfCircle());

[LOG]: "Area of Square",  36 
[LOG]: "Area of Rectangle",  50 
[LOG]: "Area of circle",  113.14285714296 
```
The above implementation of finding the area of geomentrical shapes like square, rectangle and circle follows `Procedural Programming` not `Object Oriented Programming`, as our interfaces are used as `Data structres` which help us to model our data.

As the `Data Structures` of different shapes follow `Procedural Programming`, there is no need of hiding the implementation of data, thus there is no need of making variables `private`.

We can add more functions in our procedure, to work with our data. 

Like we can add a function like sumOfAllSidesOfSquare() that can return total length of all the sides combined and lot more functions that can work on the defined Data Structure.

But adding new Data Structures is hard as the functions should also change.

But it's totaly opposite, when we do Object Oriented Programming.

Let's see an OOP example of the above,

```
interface Shape {
    areaOfSquare(): number;
    areaOfRectangle(): number;
    areaOfCircle(): number;
}

class Geomentry implements Shape {
    _square!: {side: number};
    _rectangle!: {length: number, width: number};
    _circle!: {radius: number};
    constructor(square: { side: number; }, 
                rectangle: { length: number; width: number; }, 
                circle: { radius: number; }) {
        this._square = square;
        this._rectangle = rectangle;
        this._circle = circle;
        }

    areaOfSquare(): number {
        return this._square.side ** 2;
        }

    areaOfRectangle(): number {
        return this._rectangle.length * this._rectangle.width;
        }

    areaOfCircle(): number {
        const pi = 3.14285;
        return pi * this._circle.radius ** 2;
        }

}

const geomentry = new Geomentry({side: 6}, 
                                {length: 10, width: 5}, 
                                {radius: 6});

console.log("Area of Square", geomentry.areaOfSquare());

console.log("Area of Rectangle", geomentry.areaOfRectangle());

console.log("Area of circle", geomentry.areaOfCircle());

[LOG]: "Area of Square",  36 
[LOG]: "Area of Rectangle",  50 
[LOG]: "Area of circle",  113.14285714296 
```

The above implementation of finding the area of geomentrical shapes like square, rectangle and circle follows `Object Oriented Programming`, as our interface named Shape is implemented as an `Object`.

As the shapes follow `Object Oriented Programming`, there is a need of hiding the implementation of data, thus we made variables `private` for the purpose of `Abstraction`.

We can add more classes by implementing the interface in our OOP code. 

But adding new `Functions` is hard as the `Classes` should also change.

Thus we come to a philosopy of,

>In Procedural programming its hard to add new Data Structures as all the functions must change. 

>In Object Oriented Programming its hard to add new functions because all the classes must change.

In `Software engineering`, we don't need to represent everything as an `Object`. 

Sometimes we need `Functions` that can work with `Data Structures` in a `Procedural code`.

There is no need of hiding the data thus no need of `Private variables`.

When we represent an `Object`, we need to hide the data. 

Which paves the way for `Private variables` for the sake of `Abstraction`.

Thus there is no need to expose the `Private variables` with `getters` and `setter` unnecessarily. 

[Visit my Blog here!](https://dogealgo.netlify.app/)