Created
June 20, 2020 01:34
-
-
Save sjmyuan/f219bcdd2b123d7d0c16c3aa27e8c30e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trait DataSourceComponent { | |
val source: DataSource | |
trait DataSource { | |
def getData: List[Int] | |
} | |
} | |
trait HttpRequestComponent { | |
val http: HttpRequest | |
trait HttpRequest { | |
def get(url: String): String | |
} | |
} | |
trait LogHttpRequestComponent extends HttpRequestComponent { | |
val http: HttpRequest = new LogHttpRequest {} | |
trait LogHttpRequest extends HttpRequest { | |
override def get(url: String): String = { | |
println(s"send request to ${url}") | |
List(1, 2, 3, 4, 5, 6).mkString(",") | |
} | |
} | |
} | |
trait HttpDataSourceComponent extends DataSourceComponent { | |
self: HttpRequestComponent => | |
val source: DataSource = new HttpDataSource {} | |
trait HttpDataSource extends DataSource { | |
override def getData: List[Int] = | |
http.get("http://example.com/data").split(",").map(_.toInt).toList | |
} | |
} | |
trait DataStoreComponent { | |
val store: DataStore | |
trait DataStore { | |
def save(data: List[Int]): Unit | |
} | |
} | |
trait DatabaseComponent { | |
val database: Database | |
trait Database { | |
def runSql(sql: String): Unit | |
} | |
} | |
trait LogDatabaseComponent extends DatabaseComponent { | |
val database: Database = new LogDatabase {} | |
trait LogDatabase extends Database { | |
override def runSql(sql: String): Unit = println(s"run sql ${sql}") | |
} | |
} | |
trait DatabaseStoreComponent extends DataStoreComponent { | |
self: DatabaseComponent => | |
val store: DataStore = new DatabaseStore {} | |
trait DatabaseStore extends DataStore { | |
override def save(data: List[Int]): Unit = | |
database.runSql(s"insert into data_table values(${data.mkString(",")})") | |
} | |
} | |
trait DataEncoderComponent { | |
val encoder: DataEncoder | |
trait DataEncoder { | |
def encode(data: List[Int]): List[Int] | |
} | |
} | |
trait PlusOneEncoderComponent extends DataEncoderComponent { | |
val encoder: DataEncoder = new PlusOneEncoder {} | |
trait PlusOneEncoder extends DataEncoder { | |
def encode(data: List[Int]): List[Int] = { | |
println(s"encoding ${data}") | |
data.map(_ + 1) | |
} | |
} | |
} | |
class DataJob { | |
self: DataSourceComponent with DataStoreComponent with DataEncoderComponent => | |
def run: Unit = { | |
val data = source.getData | |
val encodedData = encoder.encode(data) | |
store.save(encodedData) | |
} | |
} | |
object Main { | |
def main() { | |
val program = new DataJob | |
with LogHttpRequestComponent | |
with DatabaseStoreComponent | |
with HttpDataSourceComponent | |
with PlusOneEncoderComponent | |
with LogDatabaseComponent | |
program.run | |
} | |
} | |
Main.main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment