我只是想知道:在Java 8中,以及在接口中添加實現的可能性(有點像Scala特性),是否有可能實現cake pattern,就像我們可以在Scala中做的那樣?與Java8的蛋糕模式可能嗎?
如果是這樣,有人可以提供代碼片段嗎?
我只是想知道:在Java 8中,以及在接口中添加實現的可能性(有點像Scala特性),是否有可能實現cake pattern,就像我們可以在Scala中做的那樣?與Java8的蛋糕模式可能嗎?
如果是這樣,有人可以提供代碼片段嗎?
與其他答案啓發我想出了以下(粗糙)類層次結構類似於在斯卡拉蛋糕模式:
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 {}
關於Java 8以上編譯爲1月9日2013年。
所以,可以的Java 8做cake- 像模式? 是的。
它和Scala一樣簡潔,還是和Java中的其他模式(即依賴注入)一樣有效? 可能不是,上面的草圖需要大量的文件,並不像Scala那樣簡潔。
總結:
val
和var
可以通過使用靜態哈希映射(和延遲初始化)或類的客戶端簡單地將值存儲在其側面(如UserService)仿效。this.getClass()
來發現我們的類型。一些實驗表明NO:
嵌套類是自動靜態的。這本質上是uncakelike:
interface Car {
class Engine { }
}
// ...
Car car = new Car() { };
Car.Engine e = car.new Engine();
error: qualified new of static class
Car.Engine e = car.new Engine();
所以,很明顯,是嵌套的接口,雖然它很難哄出來的錯誤信息:
interface Car {
interface Engine { }
}
// ...
Car car = new Car() { };
class Yo implements car.Engine {
}
error: package car does not exist
class Yo implements car.Engine {
// ...
class Yo implements Car.Engine {
}
// compiles ok.
因此,沒有實例成員類,你做沒有路徑相關的類型,這對於蛋糕模式來說基本上是必需的。所以至少,不,不是以直接的方式, 這是不可能的。
也許你可以做這樣的事情在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"
你的第一示例編譯和運行如預期中的Java 8. –
忽略的Java 8可以將這些新功能更好理論上使用編譯時間AspectJ ITDs在Java 5及更高版本中執行Cake Pattern。
AspectJ DTO's allow you to make Mixins。唯一令人討厭的是你將不得不製作兩個工件:方面(ITD)和界面。然而,ITD允許你做一些瘋狂的事情,比如爲實現接口的類添加註釋。
我做了一個小的證明,在概念上這家最近。你可以看到這裏的博客文章:http://thoredge.blogspot.no/2013/01/cake-pattern-in-jdk8-evolve-beyond.html和github回購這裏:https://github.com/thoraage/cake-db-jdk8
基本上你可以做到這一點,但你至少面臨兩個障礙,使它比斯卡拉更光滑。首先,Scala特徵可以具有狀態,而Java的接口不能。許多模塊需要狀態。這可以通過創建一個通用的狀態組件來保存這些信息來解決,但這需要在一個類中。至少部分。第二個問題是,接口中的嵌套類更類似於類中的靜態嵌套類。所以你不能直接從模塊類訪問接口方法。默認的接口方法可以訪問這個範圍,並且可以將它添加到模塊類的構造函數中。
狀態可以通過使用靜態身份映射,映射從(例如 - >值)來處理(在很不雅方式)對於每個字段,然後懶惰地在初始化它每個領域的獲得者。 –
您應該能夠訪問'this'和'this.getClass()'的默認方法的身體,你可以通過一個微弱的標識映射添加額外的狀態。然而在日誌記錄的例子中,它不是java的方式;添加一個實例字段「最終Logger記錄器= Logger.of(this);'來實現mixin效果的簡單/舊解決方案沒有任何問題。 – irreputable
你是對的,更新了帖子以反映這一點。 –
謝謝,很好的回答! –