I recently discovered that PowerShell supports classes, so I started to wonder if I could code using standard Object-Oriented techniques in PowerShell. Starting with PowerShell 5.0 classes are supported. If you are going to use classes in PowerShell, I strongly suggest that you use pwsh 7.0 or above. Support there is much better than in the earlier versions.
In this series of posts, I am going to discuss how object-oriented programming with PowerShell, what works well, and were, shall we say, there is room for improvement.
As you probably know there are three principles of object orientation: encapsulation, inheritance, and polymorphism.
Let's start our discussion with encapsulation, the ability bundle data and methods into a single unit, typically a class.
We can encapsulate data and methods inside of a class in PowerShell.
class Foo {Foo([int] value) {$this.value = value}[int] GetValue(){return $this.value}hidden [int] $value}
Class Foo has one data element and two methods, a constructor and a getter. One of the limitations of PowerShell is that it is not possible to hide the internal state of a class. This is typically done by determining which parts (data and methods) of the class comprise the public interface and which data and methods are internal implementation details that should not be accessed outside of the class or derived classes.
In the case of Foo, if the intent is that the value is only settable at object construction, there is no way enforce this.
But, what about the keyword `hidden` before the data member, you may ask. I find the keyword hidden to be a good convention for letting the users and maintainers of the class know that the intent is to keep the method or data member, private. However, hidden data elements and members are public and therefore accessible outside of the class. The keywork hidden just hides the data member or method when you use the Get-Member cmdlet on the class.
In this area PowerShell is lacking. There is no way to truly make methods or data private (or protected) to the class.
I find that when coding one of the best pieces of advice was given by Dr. Seuss in Horton Hears a Who. “Say what you mean and mean what you say”. What I mean by that is code should express the intent, and the intent expresses should be what is intended. In the case of object-oriented languages, data and methods that should only be accessed by the class should be private, those that can be accessed by derived class should be protected, and only those that are available to everyone should be public. Unfortunately, in PowerShell there is no way to indicate something is protected and hidden is more of a suggestion than something enforceable for private data and methods.
In PowerShell, we can encapsulate, but we cannot protect the class internals from access by outsiders. You will need to decide if this works for your project. Next up: inheritance.
No comments:
Post a Comment