2011-10-21 76 views
3

下面是我的一些Java代碼使用訪客模式在Java中實現toString方法?

public List<OBJ> a = new ArrayList<OBJ>(); 
public String A; 
public String B; 
public String C; 
for (OBJ o : a) { 
    // .... TODO 
} 

所以我有一個接口OBJ並有實現OBJ說X,Y,Z。所以我存儲在列表中的一個X/Y/Z對象的三個對象。現在說我想要通過循環,如果o是實例X在A中存儲X.value,如果Y在B中存儲Y.value,並且Z在Z中存儲Z.value,那麼問題實際上是怎麼回事你找出哪個對象類型o是(X,Y,Z)來將它們的值存儲在正確的字符串中。

注意:我想使用Visitor pattern或類似的東西,但我沒有確切掌握它,所以我要求您的幫助。

這意味着沒有INSTANCEOF(S)或類型轉換和像

interface OBJ { 
    void blah(); 
} 

class X implements OBJ { 
    public void blah(); 
} // etc 

由於沒有專門的方法!我真的想要得到軟件工程的這個重要方面!

嘿哇感謝詳細和快速響應,但我的情況有點更復雜,對不起,我沒有之前添加此。

所以字符串A,B,C,實際上裝在另一個類像

class ARGH { 
    public List<OBJ> a = new ArrayList<OBJ>(); 
    public String A; 
    public String B; 
    public String C; 
    //invisible constructor here 
    public String toString() { 
     for (OBJ o : a) { 
      // .... TODO 
     } 
     return "some string" 
    } 
} 
public void main (String[] args) { 
    ARGH argh = new ARGH(); 
    // Setup some X, Y, Z objects and their values here 
    String D = argh.toString(); 
    // Do something to D 
} 

所以字符串和列表實際上是沒有全局變量,所以我不認爲這會工作:

ObjVisitor v = new ObjVisitor() { 
    @Override 
    public void visit(X x) { 
     A = x.value(); 
    } 
    // And so on. 
} 

我假設我必須以某種方式將字符串A,B,C傳入訪問方法,但我不知道如何執行該操作並仍然保留訪問者模式。

+0

我不知道你能做到這一點,通過A,B和C到方法將無法正常工作,由於他們的不變性。您可以創建A,B和C StringBuilders並將它們作爲參數傳遞給ObjVisitor構造函數,然後它將引用這些StringBuilders? –

回答

3

在堅果殼你會做這樣的:

  1. 一個visit - 方法爲每種類型創建一個Visitor接口ObjVisitor
  2. 添加一個抽象accept(ObjVisitor v)OBJ
  3. 爲每個OBJ實施添加一個accept(ObjVisitor v) { v.visit(this); }
  4. 呼叫o.accept(yourVisitorImpl)在循環中。

確實確實從Bringer128得到了一些代碼。我詳細闡述了一下,並添加了String-stuff。

import java.util.*; 

interface OBJ { 
    String accept(ObjVisitor v); 
} 

interface ObjVisitor { 
    String visit(X x); 
    String visit(Y y); 
    String visit(Z z); 
} 

class X implements OBJ { 
    public String accept(ObjVisitor v){ return v.visit(this); } 
} 
class Y implements OBJ { 
    public String accept(ObjVisitor v) { return v.visit(this); } 
} 
class Z implements OBJ { 
    public String accept(ObjVisitor v) { return v.visit(this); } 
} 

用法:

class Test { 
    public static void main(String[] args) { 

     List<OBJ> objs = Arrays.asList(new Z(), new X()); 

     ObjVisitor toStringVisitor = new ObjVisitor() { 
      public String visit(X x) { return "X object"; } 
      public String visit(Y y) { return "Y object"; } 
      public String visit(Z z) { return "Z object"; } 
     }; 

     String result = ""; 
     for (OBJ o : objs) 
      result += o.accept(toStringVisitor) + "\n"; 

     System.out.println(result); 

     // Prints 
     // Z object 
     // X object 
    } 
} 

另一種(也許是更好的辦法)是讓訪問者執行維護一個StringBuilder,讓參觀的方法返回void,並在循環之後只需要調用stringVisitor.getCurrentString()或類似的東西。

+0

我會在這裏等你。 :) – LiuwkCn

0

aioobe爲你拼寫出來,但這裏是實現的樣子。

interface OBJ { 
    void blah(); 
    // New method! 
    void accept(ObjVisitor v); 
} 

class X implements OBJ { 
    public void blah() {} 
    @Override 
    public void accept(ObjVisitor v) { 
    v.visit(this); 
    } 
} 

interface ObjVisitor { 
    public void visit(X x); 
    public void visit(Y y); 
} 

現在使用它:

public List<OBJ> a = new ArrayList<OBJ>(); 
public String A; 
public String B; 
public String C; 

public void myMethod() { 

    ObjVisitor v = new ObjVisitor() { 
    @Override 
    public void visit(X x) { 
     A = x.value(); 
    } 
    // And so on. 
    } 
    for (OBJ o : a) { 
    o.accept(v); 
    } 
} 
相關問題