Despite embracing composition over inheritance, the fragile base class issue can still arise in Go, albeit in a less severe form.
The problem occurs when changes to a base class break its subclasses. In languages with virtual methods (such as Java), overriding methods in subclasses can lead to unexpected behavior if the base class is modified.
In Go, however, there is no polymorphism (overrideable methods). When embedding a type, the embedded methods are promoted to the wrapper struct but cannot be overridden. This mitigates the fragile base class problem, as the promoted methods cannot be altered by subclasses.
In Java:
<code class="java">class Counter { int value; void inc() { value++; } void incBy(int n) { value += n; } } class MyCounter extends Counter { void inc() { incBy(1); } }</code>
If Counter.incBy() is modified to inc() many times, MyCounter will enter an infinite loop.
In Go:
<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 with the same modification to Counter.incBy() as in the Java example, MyCounter will still function correctly, as it directly calls Counter.Inc(). The base class's methods are unaffected by any changes in the subclass.
While the fragile base class issue is less prevalent in Go due to the absence of polymorphism, it is important to consider the potential implications of base class changes when embedding types in structs.
The above is the detailed content of Does Go\'s Composition Model Mitigate the Fragile Base Class Issue?. For more information, please follow other related articles on the PHP Chinese website!