From c499c26cd03c1cc49a68a13d9168bb416a859f81 Mon Sep 17 00:00:00 2001 From: Matteo Di Pirro Date: Fri, 19 Jul 2024 08:38:44 +0200 Subject: [PATCH 1/2] SCALA-601 Add code for stackable trait article --- .../stackabletrait/DecoratorExample.scala | 43 +++++++++++++++++++ .../scala/stackabletrait/MixinExample.scala | 24 +++++++++++ .../StackableTraitExample.scala | 41 ++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 scala-core-modules/scala-core-8/src/main/scala/com/baeldung/scala/stackabletrait/DecoratorExample.scala create mode 100644 scala-core-modules/scala-core-8/src/main/scala/com/baeldung/scala/stackabletrait/MixinExample.scala create mode 100644 scala-core-modules/scala-core-8/src/main/scala/com/baeldung/scala/stackabletrait/StackableTraitExample.scala diff --git a/scala-core-modules/scala-core-8/src/main/scala/com/baeldung/scala/stackabletrait/DecoratorExample.scala b/scala-core-modules/scala-core-8/src/main/scala/com/baeldung/scala/stackabletrait/DecoratorExample.scala new file mode 100644 index 000000000..7a91806b2 --- /dev/null +++ b/scala-core-modules/scala-core-8/src/main/scala/com/baeldung/scala/stackabletrait/DecoratorExample.scala @@ -0,0 +1,43 @@ +package com.baeldung.scala.stackabletrait + +object DecoratorExample { + trait IntTransformation { + def transform(value: Int): Int = value + } + + class TransformationDecorator(wrappee: IntTransformation) + extends IntTransformation { + override def transform(value: Int): Int = wrappee.transform(value) + } + + class DoubleDecorator(wrappee: IntTransformation) + extends TransformationDecorator(wrappee) { + override def transform(value: Int): Int = + super.transform(value * 2) + } + + class LogInt(wrappee: IntTransformation) + extends TransformationDecorator(wrappee) { + override def transform(value: Int): Int = { + println(s"Transforming value: $value") + super.transform(value) + } + } + + class CustomDecorator(f: Int => Int, wrappee: IntTransformation) + extends TransformationDecorator(wrappee) { + override def transform(value: Int): Int = + super.transform(f(value)) + } + + @main + def mainDec(): Unit = { + val identity = new IntTransformation {} + + val withLogging = new LogInt(identity) + val withDouble = new DoubleDecorator(withLogging) + val withCustom = new CustomDecorator(_ + 1, withDouble) + + println(s"With increment, double, and logging: ${withCustom.transform(5)}") + } +} diff --git a/scala-core-modules/scala-core-8/src/main/scala/com/baeldung/scala/stackabletrait/MixinExample.scala b/scala-core-modules/scala-core-8/src/main/scala/com/baeldung/scala/stackabletrait/MixinExample.scala new file mode 100644 index 000000000..79e225bd6 --- /dev/null +++ b/scala-core-modules/scala-core-8/src/main/scala/com/baeldung/scala/stackabletrait/MixinExample.scala @@ -0,0 +1,24 @@ +package com.baeldung.scala.stackabletrait + +object MixinExample { + trait Person { + val name: String + val country: String + } + + case class ItalianPerson(name: String) extends Person { + val country = "Italy" + } + + trait WithPrettyPrinting extends Person { + def prettyPrint: String = + s"""Name: $name + |Country: $country""".stripMargin + } + + @main + def main(): Unit = + val italian = new ItalianPerson("Mario") with WithPrettyPrinting + println(italian) + println(italian.prettyPrint) +} diff --git a/scala-core-modules/scala-core-8/src/main/scala/com/baeldung/scala/stackabletrait/StackableTraitExample.scala b/scala-core-modules/scala-core-8/src/main/scala/com/baeldung/scala/stackabletrait/StackableTraitExample.scala new file mode 100644 index 000000000..bb8dbbd62 --- /dev/null +++ b/scala-core-modules/scala-core-8/src/main/scala/com/baeldung/scala/stackabletrait/StackableTraitExample.scala @@ -0,0 +1,41 @@ +package com.baeldung.scala.stackabletrait + +object StackableTraitExample { + trait IntTransformation { + def transform(value: Int): Int = value + } + + trait DoubleTransformation extends IntTransformation { + override def transform(value: Int): Int = + super.transform(value * 2) + } + + trait LogInt extends IntTransformation { + override def transform(value: Int): Int = { + println(s"Transforming value: $value") + super.transform(value) + } + } + + trait CustomTransformation(f: Int => Int) extends IntTransformation { + override def transform(value: Int): Int = + super.transform(f(value)) + } + + @main + def mainST(): Unit = { + val logAndDouble = new IntTransformation + with DoubleTransformation + with LogInt {} + val doubleAndLog = new IntTransformation + with LogInt + with DoubleTransformation {} + val logAndCustom = new IntTransformation + with CustomTransformation(_ + 1) + with LogInt {} + + println(s"Log and double: ${logAndDouble.transform(5)}") + println(s"Double and log: ${doubleAndLog.transform(5)}") + println(s"Log and increment: ${logAndCustom.transform(5)}") + } +} From 8398deb444f2659b7fe0948e37e82132d4540d07 Mon Sep 17 00:00:00 2001 From: Matteo Di Pirro Date: Mon, 22 Jul 2024 18:04:35 +0200 Subject: [PATCH 2/2] SCALA-601 Add example with different base and core traits --- ...eTraitWithExplicitBaseAndCoreExample.scala | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 scala-core-modules/scala-core-8/src/main/scala/com/baeldung/scala/stackabletrait/StackableTraitWithExplicitBaseAndCoreExample.scala diff --git a/scala-core-modules/scala-core-8/src/main/scala/com/baeldung/scala/stackabletrait/StackableTraitWithExplicitBaseAndCoreExample.scala b/scala-core-modules/scala-core-8/src/main/scala/com/baeldung/scala/stackabletrait/StackableTraitWithExplicitBaseAndCoreExample.scala new file mode 100644 index 000000000..83bb6332d --- /dev/null +++ b/scala-core-modules/scala-core-8/src/main/scala/com/baeldung/scala/stackabletrait/StackableTraitWithExplicitBaseAndCoreExample.scala @@ -0,0 +1,45 @@ +package com.baeldung.scala.stackabletrait + +object StackableTraitWithExplicitBaseAndCoreExample { + trait BaseIntTransformation { + def transform(value: Int): Int + } + + trait CoreIntTransformation extends BaseIntTransformation { + def transform(value: Int): Int = value + } + + trait DoubleTransformation extends CoreIntTransformation { + override def transform(value: Int): Int = + super.transform(value * 2) + } + + trait LogInt extends CoreIntTransformation { + override def transform(value: Int): Int = { + println(s"Transforming value: $value") + super.transform(value) + } + } + + trait CustomTransformation(f: Int => Int) extends CoreIntTransformation { + override def transform(value: Int): Int = + super.transform(f(value)) + } + + @main + def mainSTE(): Unit = { + val logAndDouble = new CoreIntTransformation + with DoubleTransformation + with LogInt {} + val doubleAndLog = new CoreIntTransformation + with LogInt + with DoubleTransformation {} + val logAndCustom = new CoreIntTransformation + with CustomTransformation(_ + 1) + with LogInt {} + + println(s"Log and double: ${logAndDouble.transform(5)}") + println(s"Double and log: ${doubleAndLog.transform(5)}") + println(s"Log and increment: ${logAndCustom.transform(5)}") + } +}