Trait/Object

com.thoughtworks.feature

Factory

Related Docs: object Factory | package feature

Permalink

trait Factory[Output] extends Serializable

A factory to create new instances, especially dynamic mix-ins.

Author:

杨博 (Yang Bo) <[email protected]>

Source
Factory.scala
Examples:
  1. Given a trait that has abstract members.

    trait Foo {
      val bar: Int
      var baz: Long
    }

    When creating a factory for the trait.

    val factory = Factory[Foo]

    Then the newInstance method of the factory should accept named arguments according to abstract members.

    val createdFromNamedArguments: Foo = factory.newInstance(bar = 1, baz = 2L)
    createdFromNamedArguments.bar should be(1)
    createdFromNamedArguments.baz should be(2L)

    When using unnamed parameters, the parameters should be passed in alphabetical order

    val createdFromUnnamedArguments: Foo = factory.newInstance(1, 2L)
    createdFromUnnamedArguments.bar should be(1)
    createdFromUnnamedArguments.baz should be(2L)
  2. ,
  3. Given two traits that have no abstract member.

    trait Foo
    trait Bar

    When creating a factory for mix-in type of the two types.

    val factory = Factory[Foo with Bar]

    Then the newInstance method of the factory should accept no parameters.

    val fooBar: Foo with Bar = factory.newInstance()
    fooBar should be(a[Foo])
    fooBar should be(a[Bar])
  4. ,
  5. Given a trait that contains an abstract method annotated as @inject.

    import com.thoughtworks.feature.Factory.inject
    trait Foo[A] {
      @inject def orderingA: Ordering[A]
    }

    When creating a factory for the trait

    val factory = Factory[Foo[Int]]

    Then the @inject method will be replaced to an implicit value.

    val foo = factory.newInstance()
    foo.orderingA should be(implicitly[Ordering[Int]])

    It will not compile if no implicit value found. For example, Foo[Symbol] requires an implicit value of type Ordering[Symbol], which is not availble.

    "Factory[Foo[Symbol]]" shouldNot compile

    If the trait does not contain abstract methods other than @inject methods, then the factory type class is a Factory.Nullary, which can be summoned by Predef.implicitly,

    val nullaryFactory = implicitly[Factory.Nullary[Foo[Int]]]

    and newInstance method is available on the Factory.Nullary as well.

    nullaryFactory.newInstance().orderingA should be(implicitly[Ordering[Int]])
Note

However, if the nested type is an alias to another type outside of the type to create, then it is allowed

trait Outer {
  type Inner = String
  val inner: Option[Inner]
}
val outer: Outer = Factory[Outer].newInstance(inner = Some("my value"))
outer.inner should be(Some("my value"))
,

This Factory disallows creating types that has an abstract member whose type depends on nested types

trait Outer {
  trait Inner
  val inner: Option[Inner]
}
"Factory.newInstance[Outer](inner = None)" shouldNot typeCheck
,

@inject works on implicit abstract methods as well.

import com.thoughtworks.feature.Factory.inject
trait Foo[A] {
  @inject implicit def orderingA: Ordering[A]
}
Factory[Foo[Int]].newInstance().orderingA should be(implicitly[Ordering[Int]])
,

Factories may be nested

import com.thoughtworks.feature.Factory.inject
trait Outer {
  trait AbstractParameterApi
  type AbstractParameter <: AbstractParameterApi
  trait InnerApi {
    def foo: AbstractParameter
  }
  type Inner <: InnerApi
  @inject val innerFactory: Factory.UnaryByName[AbstractParameter, Inner]
}
Factory[Outer]
Linear Supertypes
Type Hierarchy
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. Factory
  2. Serializable
  3. Serializable
  4. AnyRef
  5. Any
Implicitly
  1. by any2stringadd
  2. by StringFormat
  3. by Ensuring
  4. by ArrowAssoc
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. All

Type Members

  1. abstract type Constructor

    Permalink

    A function type that returns Output.

    A function type that returns Output.

    The parameter types are all abstract members in Output

Abstract Value Members

  1. abstract val newInstance: Constructor

    Permalink

    Returns an instance of Output, which overrides abstract members in Output according to parameters pass to this newInstance method.

Concrete Value Members

  1. final def !=(arg0: Any): Boolean

    Permalink
    Definition Classes
    AnyRef → Any
  2. final def ##(): Int

    Permalink
    Definition Classes
    AnyRef → Any
  3. def +(other: String): String

    Permalink
    Implicit information
    This member is added by an implicit conversion from Factory[Output] to any2stringadd[Factory[Output]] performed by method any2stringadd in scala.Predef.
    Definition Classes
    any2stringadd
  4. def ->[B](y: B): (Factory[Output], B)

    Permalink
    Implicit information
    This member is added by an implicit conversion from Factory[Output] to ArrowAssoc[Factory[Output]] performed by method ArrowAssoc in scala.Predef.
    Definition Classes
    ArrowAssoc
    Annotations
    @inline()
  5. final def ==(arg0: Any): Boolean

    Permalink
    Definition Classes
    AnyRef → Any
  6. final def asInstanceOf[T0]: T0

    Permalink
    Definition Classes
    Any
  7. def clone(): AnyRef

    Permalink
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  8. def ensuring(cond: (Factory[Output]) ⇒ Boolean, msg: ⇒ Any): Factory[Output]

    Permalink
    Implicit information
    This member is added by an implicit conversion from Factory[Output] to Ensuring[Factory[Output]] performed by method Ensuring in scala.Predef.
    Definition Classes
    Ensuring
  9. def ensuring(cond: (Factory[Output]) ⇒ Boolean): Factory[Output]

    Permalink
    Implicit information
    This member is added by an implicit conversion from Factory[Output] to Ensuring[Factory[Output]] performed by method Ensuring in scala.Predef.
    Definition Classes
    Ensuring
  10. def ensuring(cond: Boolean, msg: ⇒ Any): Factory[Output]

    Permalink
    Implicit information
    This member is added by an implicit conversion from Factory[Output] to Ensuring[Factory[Output]] performed by method Ensuring in scala.Predef.
    Definition Classes
    Ensuring
  11. def ensuring(cond: Boolean): Factory[Output]

    Permalink
    Implicit information
    This member is added by an implicit conversion from Factory[Output] to Ensuring[Factory[Output]] performed by method Ensuring in scala.Predef.
    Definition Classes
    Ensuring
  12. final def eq(arg0: AnyRef): Boolean

    Permalink
    Definition Classes
    AnyRef
  13. def equals(arg0: Any): Boolean

    Permalink
    Definition Classes
    AnyRef → Any
  14. def finalize(): Unit

    Permalink
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( classOf[java.lang.Throwable] )
  15. def formatted(fmtstr: String): String

    Permalink
    Implicit information
    This member is added by an implicit conversion from Factory[Output] to StringFormat[Factory[Output]] performed by method StringFormat in scala.Predef.
    Definition Classes
    StringFormat
    Annotations
    @inline()
  16. final def getClass(): Class[_]

    Permalink
    Definition Classes
    AnyRef → Any
  17. def hashCode(): Int

    Permalink
    Definition Classes
    AnyRef → Any
  18. final def isInstanceOf[T0]: Boolean

    Permalink
    Definition Classes
    Any
  19. final def ne(arg0: AnyRef): Boolean

    Permalink
    Definition Classes
    AnyRef
  20. final def notify(): Unit

    Permalink
    Definition Classes
    AnyRef
  21. final def notifyAll(): Unit

    Permalink
    Definition Classes
    AnyRef
  22. final def synchronized[T0](arg0: ⇒ T0): T0

    Permalink
    Definition Classes
    AnyRef
  23. def toString(): String

    Permalink
    Definition Classes
    AnyRef → Any
  24. final def wait(): Unit

    Permalink
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  25. final def wait(arg0: Long, arg1: Int): Unit

    Permalink
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  26. final def wait(arg0: Long): Unit

    Permalink
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  27. def [B](y: B): (Factory[Output], B)

    Permalink
    Implicit information
    This member is added by an implicit conversion from Factory[Output] to ArrowAssoc[Factory[Output]] performed by method ArrowAssoc in scala.Predef.
    Definition Classes
    ArrowAssoc

Inherited from Serializable

Inherited from Serializable

Inherited from AnyRef

Inherited from Any

Inherited by implicit conversion any2stringadd from Factory[Output] to any2stringadd[Factory[Output]]

Inherited by implicit conversion StringFormat from Factory[Output] to StringFormat[Factory[Output]]

Inherited by implicit conversion Ensuring from Factory[Output] to Ensuring[Factory[Output]]

Inherited by implicit conversion ArrowAssoc from Factory[Output] to ArrowAssoc[Factory[Output]]

Ungrouped