Scala 中的复合设计模式?

发布于 2024-10-17 01:22:43 字数 665 浏览 5 评论 0原文

在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中编写它?特别是我无法理解如何编写接口并实现它?

In java I can implement the composite design pattern as follows:

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
      }
 }

How can I write it in scala? In particular I am having trouble understanding how to write an interface and implement it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦断已成空 2024-10-24 01:22:43

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

In Scala, a Trait without any concrete methods is just an interface. So a direct translation would be:

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() = ...
}

Though if you want more idiomatic Scala, I'd recommend something like this as a definition for Composite:

class Composite extends Component {
  def operation() = children foreach { _.operation() }
  def +=(child: Component) = ...
  def -=(child: Component) = ...
  def apply(index: Int) = ...
}

To be used as:

val comp = new Composite
comp += child1
comp += child2
comp -= child1
val firstChild = comp(0)

If you want to take this to a logical conclusion, I'd advocate building the whole composite structure as an immutable Directed Acyclic Graph (though I appreciate that this often isn't possible):

case class Composite(children: Component*) extends Component {
  def operation() = children foreach { _.operation() }
}

val comp = Composite(child1, Composite(child2, child3), child4)
娇纵 2024-10-24 01:22:43

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")  
    }
}

Something like

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") 
 }

This is a very direct translation. Often an immutable solution is preferred in Scala. Another difference is, that you often use pattern matching instead of inheritance. E.g. you could rewrite the example by removing operation() from Component and Leaf and writing instead

trait Component{
    def operation():Unit = this match {
      case c:Composite => c.children.foreach(_.operation())
      case leaf:Leaf => println("leaf")  
    }
}
柠檬心 2024-10-24 01:22:43

更干净的不可变方式是:

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

A cleaner immutable way would be:

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
情绪少女 2024-10-24 01:22:43

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

值得一提的是,特征比 Java 接口更强大,并且可以包括实现和接口规范。

Functionality presented in Java as an interface can be coded in Scala as a trait

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
      }
 }

It's worth saying that traits are more powerful than Java interfaces, and can include implementation as well as interface specifications.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文