Skip to content

Instantly share code, notes, and snippets.

@mathieuancelin
Created March 16, 2017 08:14
Show Gist options
  • Save mathieuancelin/87ca21df14b2c11c8671b299c08e42f5 to your computer and use it in GitHub Desktop.
Save mathieuancelin/87ca21df14b2c11c8671b299c08e42f5 to your computer and use it in GitHub Desktop.
import com.google.common.collect.Lists;
import java.util.List;
public class Cake {
public static class User {
public final String name;
public User(String name) {
this.name = name;
}
@Override
public String toString() {
return "User(" + name + ")";
}
}
public static interface UserService {
List<User> allUsers();
}
public static interface UserServiceComponent {
UserService userService();
}
public static interface InMemoryUserServiceComponent extends UserServiceComponent {
default UserService userService() {
return InMemoryUserService.instance;
}
}
public static interface CachedUserServiceComponent extends UserServiceComponent {
default UserService userService() {
return CachedUserService.instance;
}
}
public static interface DefaultUserServiceComponent extends UserServiceComponent {
default List<User> allUsers() {
return Lists.newArrayList();
}
}
private static class InMemoryUserService implements UserService {
public static final InMemoryUserService instance = new InMemoryUserService();
public List<User> allUsers() {
return Lists.newArrayList(new User("Billy"), new User("Bob"));
}
}
private static class CachedUserService implements UserService {
public static final CachedUserService instance = new CachedUserService();
public List<User> allUsers() {
return Lists.newArrayList(new User("Jane"), new User("Jill"));
}
}
public static interface Application extends UserServiceComponent {}
public static class ApplicationInMemory implements Application, InMemoryUserServiceComponent {}
public static class ApplicationCached implements Application, CachedUserServiceComponent {}
public static void main(String ... args) {
Application app1 = new ApplicationInMemory();
Application app2 = new ApplicationCached();
System.out.println(app1.userService().allUsers());
System.out.println(app2.userService().allUsers());
}
}
case class User(name: String)
trait UserService {
def users(): Seq[User]
}
trait UserServiceComponent {
val userService: UserService
}
trait InMemoryUserServiceComponent extends UserServiceComponent {
override val userService: UserService = new InMemoryUserService()
class InMemoryUserService extends UserService {
override def users(): Seq[User] = Seq(User("Billy"), User("Bobby"))
}
}
trait CachedUserServiceComponent extends UserServiceComponent {
override val userService: UserService = new CachedUserService()
class CachedUserService extends UserService {
override def users(): Seq[User] = Seq(User("Jane"), User("Jill"))
}
}
trait DefaultUserServiceComponents extends UserServiceComponent { self: UserServiceComponent =>
override val userService: UserService = new UserService {
override def users(): Seq[User] = Seq.empty[User]
}
}
trait Application extends UserServiceComponent
trait ApplicationInMemory extends Application with DefaultUserServiceComponents with InMemoryUserServiceComponent
trait ApplicationCached extends Application with DefaultUserServiceComponents with CachedUserServiceComponent
object Test extends App {
val app1: Application = new ApplicationInMemory { }
val app2: Application = new ApplicationCached { }
println(app1.userService.users())
println(app2.userService.users())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment