簡體   English   中英

Scala 中的復合設計模式?

[英]Composite design pattern in Scala?

在java中,我可以實現復合設計模式如下:

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中寫它? 特別是我無法理解如何編寫接口並實現它?

在 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)

類似的東西

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 中首選不可變的解決方案。 另一個區別是,您經常使用模式匹配而不是繼承。 例如,您可以通過從ComponentLeaf刪除operation()並改為編寫來重寫示例

trait Component{
    def operation():Unit = this match {
      case c:Composite => c.children.foreach(_.operation())
      case leaf:Leaf => println("leaf")  
    }
}

在 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 接口更強大,可以包括實現和接口規范。

更干凈的不可變方式是:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM