使用Java8的蛋糕模式可能吗?
2022-09-01 12:02:58
						我只是想知道:有了Java 8,以及在接口中添加实现的可能性(有点像Scala特征),是否有可能实现蛋糕模式,就像我们在Scala中所做的那样?
如果是,有人可以提供代码片段吗?
我只是想知道:有了Java 8,以及在接口中添加实现的可能性(有点像Scala特征),是否有可能实现蛋糕模式,就像我们在Scala中所做的那样?
如果是,有人可以提供代码片段吗?
从其他答案中汲取灵感,我想出了以下(粗略的)类层次结构,类似于Scala中的蛋糕模式:
interface UserRepository {
    String authenticate(String username, String password);
}
interface UserRepositoryComponent {
    UserRepository getUserRepository();
}
interface UserServiceComponent extends UserRepositoryComponent {
    default UserService getUserService() {
        return new UserService(getUserRepository());
    }
}
class UserService {
    private final UserRepository repository;
    UserService(UserRepository repository) {
        this.repository = repository;
    }
    String authenticate(String username, String password) {
        return repository.authenticate(username, password);
    }
}
interface LocalUserRepositoryComponent extends UserRepositoryComponent {
    default UserRepository getUserRepository() {
        return new UserRepository() {
            public String authenticate(String username, String password) {
                return "LocalAuthed";
            }
        };
    }
}
interface MongoUserRepositoryComponent extends UserRepositoryComponent {
    default UserRepository getUserRepository() {
        return new UserRepository() {
            public String authenticate(String username, String password) {
                return "MongoAuthed";
            }
        };
    }
}
class LocalApp implements UserServiceComponent, LocalUserRepositoryComponent {}
class MongoApp implements UserServiceComponent, MongoUserRepositoryComponent {}
以上内容于 2013 年 1 月 9 日在 Java 8 上编译。
那么,Java 8 能做一个类似蛋糕的模式吗?是的。
它是像Scala一样简洁,还是像Java中的其他模式(即依赖注入)一样有效?可能不是,上面的草图需要大量的文件,并且不像Scala那样简洁。
综上所述:
val并且可以通过使用静态哈希映射(和延迟初始化)来模拟,或者由类的客户端简单地将值存储在其一侧(如UserService所做的那样)。varthis.getClass()也许你可以在Java 8中做这样的事情。
interface DataSource
{
    String lookup(long id);
}  
interface RealDataSource extends DataSource
{
    default String lookup(long id){ return "real#"+id; }
}  
interface TestDataSource extends DataSource
{
    default String lookup(long id){ return "test#"+id; }
}  
abstract class App implements DataSource
{
    void run(){  print( "data is " + lookup(42) ); }
}  
class RealApp extends App implements RealDataSource {}
new RealApp().run();  // prints "data is real#42"
class TestApp extends App implements TestDataSource {}
new TestApp().run();  // prints "data is test#42"
但它绝不比普通/旧方法更好。
interface DataSource
{
    String lookup(long id);
}  
class RealDataSource implements DataSource
{
    String lookup(long id){ return "real#"+id; }
}  
class TestDataSource implements DataSource
{
    String lookup(long id){ return "test#"+id; }
}  
class App
{
    final DataSource ds;
    App(DataSource ds){ this.ds=ds; }
    void run(){  print( "data is " + ds.lookup(42) ); }
}  
new App(new RealDataSource()).run();  // prints "data is real#42"
new App(new TestDataSource()).run();  // prints "data is test#42"