Last active
November 24, 2016 22:20
-
-
Save mrcmatuszak/b94d3ae5041968c170ea20d9c833bebf 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
case class User(id: Long, name: String) | |
/** | |
Następujący scenariusz | |
UserService zależy od UserRepository. UserRepository wyciąga dane np z bazy. | |
Kilka przypadków | |
1. UserService zależy bezpośrednio od UserRepository (który jest klasą) | |
2. UserService zależy od AbstractUserRepository (który jest traitem) | |
3. Każda operacja z UserRepository jest wyciągnięta do oddzielnego traita (z superclass UserRepository) i UserService zależy od | |
triatów z niezależnymi operacjami | |
Założenia | |
1. UserRepository zależy od połączenia do bazy i też przyjmuje jakiś argumenty | |
2. UserService wykonuje więcej niż tylko delegowanie do repository | |
*/ | |
// Atomowe operacje wyciągnięte do traitów | |
trait AbstractUserFind { | |
val findUser: Long => User | |
} | |
trait AbstractUserCreate { | |
val createUser: Long => String => User | |
} | |
trait AbstractUserUpdate { | |
val updateUser: Long => String => User | |
} | |
// java-style abstract repository (dao) | |
trait AbstractUserRepository { //albo extends AbstractUserFind with ... | |
val findUser: Long => User | |
val createUser: Long => String => User | |
val updateUser: Long => String => User | |
} | |
// implementacja | |
trait /* or class*/ UserRepository //tu jest trait, żeby przypadek z self-type się skompilował, zazwyczaj spotyka się class | |
extends AbstractUserRepository | |
with AbstractUserFind | |
with AbstractUserCreate | |
with AbstractUserUpdate { | |
override val findUser: Long => User = id => User(id, "name") | |
override val createUser: Long => String => User = id => name => User(id, name) | |
override val updateUser: Long => String => User = id => name => findUser(id).copy(name = name) | |
} | |
trait abstract_field { | |
trait UserService { | |
def repository: UserRepository | |
def findUser(id: Long): User = repository.findUser(id) | |
} | |
class UserServiceImpl { | |
val repository = new UserRepository {} | |
} | |
object TestCase { | |
val mockRepo = new UserRepository { | |
override val findUser: Long => User = id => User(id, "name") //potrzebujemy tylko tej metody do testu, ale musimy mockować pozostałe | |
override val createUser: Long => String => User = id => name => User(id, name) | |
override val updateUser: Long => String => User = id => name => findUser(id).copy(name = name) | |
} | |
val service = new UserService { | |
override val repository = mockRepo | |
} | |
service.findUser(1L) == User(1L, "name") | |
} | |
} | |
trait self_type { | |
trait UserService { | |
self: UserRepository => | |
} | |
class UserServiceComponent extends UserService with UserRepository | |
//podobnie jak wyżej musimy dostarczyć implementacje wszystkich metod | |
} | |
trait field { | |
class UserService(repo: UserRepository) { | |
def findUser(id: Long): User = repo.findUser(id) | |
} | |
} | |
trait def_param { | |
class UserService { | |
def createUser(id: Long, name: String)(finder: AbstractUserCreate): User = finder.createUser(id)(name) | |
def findUser(id: Long)(find: Long => User): User = find(id) | |
} | |
object UserServiceTest { | |
val service = new UserService | |
def assertUser = { | |
val repo: Long => User = id => User(id, "name") | |
service.findUser(1L)(repo) == User(1, "name") | |
} | |
} | |
object UserServiceTest2 { | |
val service = new UserService | |
def assertUser = { | |
val repo = new AbstractUserCreate { | |
val createUser: Long => String => User = id => name => User(id, name) | |
} | |
service.createUser(1L, "name")(repo) == User(1L, "name") | |
} | |
} | |
{ | |
val service = new UserService | |
val repo = new UserRepository { } | |
val user = service.findUser(1L)(repo.findUser) | |
} | |
{ | |
val service = new UserService | |
val repo = new UserRepository { } | |
val user = service.createUser(1L, "name")(repo) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment