在java中,我可以按如下方式实现composite design pattern:
interface Component{
void operation();
}
class Composite implements Component{
@override
public void operation(){
for(Child child in children){
child.operation();
}
}
public void add(Component child){//implementation}
public void remove(Component child){//implementation}
public void getChild(int index);
}
class Leaf implements Component{
@override
public void operation(){
//implementation
}
}
如何在scala中编写它?特别是我无法理解如何编写接口并实现它?
答案 0 :(得分:4)
像
这样的东西import scala.collection.mutable.ListBuffer
trait Component{
def operation():Unit
}
class Composite extends Component{
val children = new ListBuffer[Component]()
def operation():Unit = children.foreach {_.operation() }
def add(child: Component):Unit = children += child
def remove(child: Component):Unit = children -= child
def getChild(index:Int) = children(index)
}:
class Leaf extends Component {
def operation():Unit = println("leaf")
}
这是一个非常直接的翻译。在Scala中,通常使用不可变的解决方案。另一个区别是,您经常使用模式匹配而不是继承。例如。您可以通过从operation()
和Component
移除Leaf
并改为编写
trait Component{
def operation():Unit = this match {
case c:Composite => c.children.foreach(_.operation())
case leaf:Leaf => println("leaf")
}
}
答案 1 :(得分:3)
在Scala中,没有任何具体方法的Trait只是一个界面。所以直接翻译是:
trait Component { def operation(): Unit }
class Composite extends Component {
def operation() = children foreach { _.operation() }
def add(child: Component) = ...
def remove(child: Component) = ...
def getChild(index: Int) = ...
}
class Leaf extends Component {
def operation() = ...
}
虽然如果你想要更多惯用的Scala,我会推荐这样的东西作为Composite
的定义:
class Composite extends Component {
def operation() = children foreach { _.operation() }
def +=(child: Component) = ...
def -=(child: Component) = ...
def apply(index: Int) = ...
}
用作:
val comp = new Composite
comp += child1
comp += child2
comp -= child1
val firstChild = comp(0)
如果你想得出一个合乎逻辑的结论,我主张将整个复合结构构建为一个不可变的有向无环图(虽然我很欣赏这通常是不可能的):
case class Composite(children: Component*) extends Component {
def operation() = children foreach { _.operation() }
}
val comp = Composite(child1, Composite(child2, child3), child4)
答案 2 :(得分:0)
Java中作为接口呈现的功能可以在Scala中编码为特征
trait Component{
def operation():Unit
}
class Composite extends Component{
@override
def operation(){
for(child<-children)
child.operation()
}
def add(child:Component){//implementation}
def remove(child:Component){//implementation}
def getChild(index:Int){//implementation}
}
class Leaf extends Component{
def operation(){
//implementation
}
}
值得一提的是,traits比Java接口更强大,可以包括实现和接口规范。
答案 3 :(得分:0)
更清洁的不变方式是:
trait Component {
def operation()
def +(other: Component): Component = new Composite(this, other)
}
class Leaf(name: String) extends Component {
override def operation(): Unit = println(name)
}
class Composite(children: Component*) extends Component {
override def operation(): Unit = children foreach { _.operation() }
}
val c = new Leaf("Tom") + new Leaf("Tim")
c.operation() // Tom Tim