Home >Backend Development >Golang >Can Go\'s Composition Model Still Suffer From the Fragile Base Class Problem?
Fragile Base Class Issue in Go: Despite Composition Over Inheritance
The fragile base class problem arises when changes to a base class can cause unexpected behavior in derived classes. This problem is commonly attributed to inheritance, where derived classes inherit the methods and fields of their base classes.
In Go, inheritance is not implemented. Instead, Go uses composition, where a struct can contain instances of other structs. However, some argue that the fragile base class issue can still exist in Go when working with embedded types.
Embedded types promote the fields and methods of the embedded type to the wrapper type. While this provides convenient access, it eliminates polymorphism. This means that methods defined in the embedded type cannot be overridden in the wrapper type, and any method calls made by the embedded type will always invoke the original definition.
As a result, the fragile base class problem is present in Go in a mitigated form. Changes to the embedded type's methods or fields can affect the wrapper type, but only if the wrapper type does not define its own methods with the same names.
Example
Consider the following Java code, where a base class Counter contains an increment method inc() and an increment-by method incBy(). A derived class MyCounter overrides inc() to call incBy(1).
<code class="java">class Counter { int value; void inc() { value++; } void incBy(int n) { value += n; } } class MyCounter extends Counter { @Override void inc() { incBy(1); } }</code>
If the incBy() method in the base class is changed to use a loop, the derived class MyCounter will enter an infinite loop because inc() calls incBy() which calls inc() again:
<code class="java">void incBy(int n) { for (; n > 0; n--) { inc(); } }</code>
In Go, the same example does not exhibit this problem because Go does not support overriding methods in embedded types:
<code class="go">type Counter struct { value int } func (c *Counter) Inc() { c.value++ } func (c *Counter) IncBy(n int) { c.value += n } type MyCounter struct { *Counter } func (m *MyCounter) Inc() { m.IncBy(1) }</code>
Even if the IncBy() method in the Counter type is modified to use a loop, the MyCounter type does not inherit this behavior because it does not define a method named Inc(). Instead, it calls the original inc() method defined in the Counter type.
Therefore, the fragile base class problem is not a major concern in Go due to the lack of polymorphism in embedded types, which prevents unexpected behavior when modifying embedded types.
The above is the detailed content of Can Go\'s Composition Model Still Suffer From the Fragile Base Class Problem?. For more information, please follow other related articles on the PHP Chinese website!