抽象类型成员(abstract type member)在组件解耦方面的运用

     当一个组件(component)需要其他接口或组件的支持时,应该如何表达?答案是将这些接口或组件进行抽象处理.

      从编程语言角度来看,参数化(parameterization)和抽象成员(abstract member)是两种主要的抽象形式。其中参数化是函数式(functional)所表达的观点,抽象成员是面向对象(Object-Oriented)所表达的观点。由于Scala同时支持函数式和面向对象两种编程风格,因此Scala都支持这两种抽象形式。事实上,在Scala中参数化是通过抽象成员的形式进行表达。 

      抽象又可以分为类型抽象(abstract type)和值抽象(abstract value). 不管是哪种抽象形式,都能被参数化或作为类的抽象成员(abstract member)进行表达。

     先看一个例子    

abstract class AbsCell {
  type T      // T is abstract type member
  val init: T   // init is abstract value member
  private var value = init 

  def get: T = value

  def set(x: T) = {
    value = x
  }
}

 AbsCell是一个抽象类,其中T是抽象类型成员, init是抽象值成员。如果需要实例化AbsCell, 必须同时给出T和init的具体定义:

val cell = new AbsCell{
   type T = Int
   val init =1
}
cell.set(cell.get * 2);

这里cell的类型是AbsCell{ type T = Int}。 但是编译后,type T =Int会被擦除(erasion).

println(cell.isInstanceOf[AbsCell{ type T=String}]);   // true
val cell2 : AbsCell{ type T = String } = cell ; // compilation error.

    接下来讲讲抽象类型成员(abstract type member)在组件解耦方面的运用。

     假设需要实现两个组件,不妨记为A组件和B组件。这两个组件互相依赖:

// A组件
object Types{
   abstract class Type{
      def sym: Symbols.Symbol  // 依赖B组件的Symbols.Symbol类
   }
}

// B组件
object Symbols{
   abstract class Symbol{
     def tpe : Types.Type   // 依赖A组件的Types.Type类
   }
}

由于两个组件互相依赖,因此无法单独编译。一种解决办法是将这两个组件的接口进行合并

// C组件
class SymbolTable{
   object Symbols{
      abstract class Symbol{
         def tpe: Types.Type
      }
   }
   object Types{
      abstract class Type{
         def sym: Symbols.Symbol
      }
   }
}

这样A,B,C组件就可以单独编译(A,B, C组件不存在其他依赖)

     这种方法存在两个问题:

1) 随着组件的增多,可能会出现大量像C组件这样的中间组件(或粘合组件) 

2)如果A,B组件分别由两个团队开发,那么这种解决办法是低效的。因为需要将两个组件互相依赖的代码抽取出来,然后融合到一个文件或类中。这种沟通和协调成本往往代价高昂。

     抽象类型成员提供了另一种解决思路

// A组件
trait Types{
  type Symbol  // 声明一个抽象类型
  abstract class Type {
    def sym: Symbol
  }
}

// B组件
trait Symbols{
  type Type   // 声明一个抽象类型
  abstract  class Symbol{
    def tpe : Type
  }
}

 这样A,B组件就能单独编译。 使用混入(mixin)方式将两个组件的接口组合起来

// 客户端组件
class SymbolTable extends  AnyRef with Types with Symbols{
   override  type Type = Types#Type   // 由于抽象类型成员Type和Types中的抽象类Type同名,因此可以省略此处的类型定义
  //  override type Symbol = String
   override  type Symbol = Symbols#Symbol // 同上

  class SubType extends super.Type{
//    def sym = new String("abc")   // if Symbol is String
    def sym = new SubSymbol()
  }

  class SubSymbol extends super.Symbol{
    def tpe = new SubType
  }

  def demo(){
    println(new SubType().sym)
    println(new SubSymbol().tpe)
  }
}

抽象类型是解决组件间互相依赖的有效手段.

 

 

 

转载于:https://my.oschina.net/aiguozhe/blog/81249

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值