官术网_书友最值得收藏!

Modules and objects

Modules are a way to organize programs. They are interchangeable and pluggable pieces of code that have well-defined interfaces and hidden implementations. In Java, modules are organized in packages. In Scala, modules are objects; just like everything else. This means that they can be parameterized, extended, and passed as parameters, and so on.

Scala modules can provide requirements in order to be used.

Using modules

We already established that modules and objects are also unified in Scala. This means that we can pass an entire module around our application. It would be useful, however, to show what a module actually looks like. Here is an example:

trait Tick { 
  trait Ticker { 
    def count(): Int 
    def tick(): Unit 
  } 
  def ticker: Ticker 
}

Here, Tick is just an interface to one of our modules. The following is its implementation:

trait TickUser extends Tick { 
  class TickUserImpl extends Ticker { 
    var curr = 0 
    
    override def count(): Int = curr 

    override def tick(): Unit = { 
      curr = curr + 1 
    } 
  } 
  object ticker extends TickUserImpl 
}

The TickUser trait is an actual module. It implements Tick and contains the code hidden inside it. We create a singleton object that will carry the implementation. Note how the name in the object is the same as the method in Tick. This would cover the need to implement it when mixing in the trait.

Similarly, we can define another interface and an implementation as follows:

trait Alarm { 
  trait Alarmer { 
    def trigger(): Unit 
  } 
  def alarm: Alarmer 
}

The implementation will be this:

trait AlarmUser extends Alarm with Tick { 
  class AlarmUserImpl extends Alarmer { 
    override def trigger(): Unit = { 
      if (ticker.count() % 10 == 0) { 
        System.out.println(s"Alarm triggered at ${ticker.count()}!") 
      } 
    } 
  } 
  object alarm extends AlarmUserImpl 
}

What is interesting here is that we extended both modules in the AlarmUser one. This shows how modules could be made to be dependent on each other. Finally, we can use our modules as follows:

object ModuleDemo extends AlarmUser with TickUser { 
  def main(args: Array[String]): Unit = { 
    System.out.println("Running the ticker. Should trigger the alarm every 10 times.") 
    (1 to 100).foreach { 
      case i => 
        ticker.tick() 
        alarm.trigger() 
    } 
  } 
}

In order for ModuleDemo to use the AlarmUser module, it is also required by the compiler to mix in TickUser or any module that mixes in Tick. This provides a possibility to plug in a different functionality.

The output of the program will be this:

Running the ticker. Should trigger the alarm every 10 times. 
Alarm triggered at 10! 
Alarm triggered at 20! 
Alarm triggered at 30! 
Alarm triggered at 40! 
Alarm triggered at 50! 
Alarm triggered at 60! 
Alarm triggered at 70! 
Alarm triggered at 80! 
Alarm triggered at 90! 
Alarm triggered at 100!
Note

Modules in Scala can be passed as any other object. They are extendable, interchangeable, and their implementation is hidden.

主站蜘蛛池模板: 乌拉特后旗| 曲阜市| 安顺市| 昌乐县| 历史| 五河县| 五大连池市| 通州区| 惠来县| 阿拉善盟| 元朗区| 益阳市| 鸡东县| 江北区| 攀枝花市| 阿荣旗| 海宁市| 琼结县| 和静县| 丹寨县| 砚山县| 台北市| 阿图什市| 广宁县| 新巴尔虎左旗| 邓州市| 安乡县| 丹江口市| 陆良县| 宜城市| 荔波县| 辉县市| 望奎县| 龙泉市| 沂源县| 无锡市| 祁连县| 墨竹工卡县| 浏阳市| 和田市| 聊城市|