Reputation: 18639
Let's see the following very simple cake pattern example:
trait PrintSomething{
def printSomeThing(s:String):Unit
}
trait PrintSomethingToConsole extends PrintSomething{
override def printSomeThing(s: String): Unit = println("Print To Console!!!")
}
trait PrintSomethingToLog extends PrintSomething{
override def printSomeThing(s: String): Unit = println("Print To Log!!!")
}
class MyAction{
self:PrintSomething =>
printSomeThing("This is it")
}
new MyAction with PrintSomethingToConsole
new MyAction with PrintSomethingToLog
I see in some blogs that the bad side of this pattern is breaking
Open-Close Principle
and Interface Segregation Principle
.
As far as I understand, there is a possibility to override printSomething
method inside MyAction and modify functionality with no matter which PrintSomething
trait was injected:
class MyAction{
self:PrintSomething =>
override def printSomeThing(s: String): Unit = println("I just Broke Open-Close Principle!!!!! ")
}
Am I right?
However I don't understand how I can violate Interface Segregation Principle
here. Can someone elaborate?
Upvotes: 1
Views: 371
Reputation: 27356
I don't see any conflict with the open-closed principle. All your classes and traits are open for extension and closed for modification. And since they only have a single method, the interface segregation principle doesn't really apply!
Even if you override printSomeThing
in your MyAction
class, you have still not violated either principle. All the objects remain open for extension (you can extend them) and closed for modification (you can not change their behaviour). An instance of PrintSomethingToLog
will always print to the log; you cannot modify it to print to the console.
An instance of PrintSomething
may have different implementations of printSomeThing
but this is just polymorphism via inheritance; it does not mean that PrintSomething
is open for modification because PrintSomething
is an interface, not a concrete class, and you can't change the interface.
Upvotes: 1