[TL; DR] 的問題是,在AWrapper
和AType
我不得不重複幾乎全部功能,其中總有語法:如何使用不兼容的封裝
public [TYPE/void] METHOD([OPT: args]) throws TestFailedException {
[OPT: TYPE result = null;]
long startTime = System.currentTimeMillis();
while (true) {
try {
beforeOperation();
[OPT: result =] ((WrappedType) element).METHOD([OPT: args]);
handleSuccess();
break;
} catch (Exception e) {
handleSoftFailure(e);
if (System.currentTimeMillis() - startTime > TIMEOUT) {
handleFailure(e);
break;
} else {
try {
Thread.sleep(WAIT_FOR_NEXT_TRY);
} catch (InterruptedException ex) {
}
}
}
}
[OPT: return result;]
}
可以說我有2班我不擁有:
public class IDontOwnThisType {
public void doA(String string) { System.out.println("doA"); }
public String doB(); {System.out.println("doB"); return "doB";}
public OtherTypeIDoNotOwn doC() {System.out.println("doC"); return new OtherTypeIDoNotOwn();}
}
public OtherTypeIDoNotOwn {
public void doD() { System.out.println("doD"); }
public String doE() { System.out.println("doE); }
public OtherTypeIDoNotOwn doF(String string) {System.out.println("doF"); return new OtherTypeIDoNotOwn();}
}
所以,我有一個接口:
public interface OperationManipulator {
void beforeOperation(); //called before operation
void handleSuccess(); //called after success
void handleSoftFailure(Exception e); //called after every failure in every try
void handleFailure(Exception e) throws TestFailedException; //called after reaching time limit
}
然後界面上方的一個延伸, 「模仿」 外部類的方法,但拋出自定義異常:
public interface IWrapper<T extends IType> extends OperationManipulator {
public void doA(String string) throws TestFailedException;
public String doB() throws TestFailedException;
public T doC() throws TestFailedException;
}
然後我們有IType
,這也延伸:
public interface IType<T extends IType> extends OperationManipulator {
public void doD() throws TestFailedException;
public String doE() throws TestFailedException;
public T doF(String string) throws TestFailedException;
}
然後,我們有以上接口的抽象實現:
public abstract class AType<T extends IType> implements IType{
Object element; // I do not own type of this object, cant modify it.
Class typeClass;
long TIMEOUT = 5000;
long WAIT_FOR_NEXT_TRY = 100;
public AType(Object element) {
this.element = element;
elementClass = this.getClass();
}
/* ... */
}
然後,我們重寫函數期從所述接口,不含OperationManipulator接口:
函數不返回任何版本:
@Override
public void doD() throws TestFailedException {
long startTime = System.currentTimeMillis();
while (true) {
try {
beforeOperation();
((OtherTypeIDoNotOwn) element).doD();
handleSuccess();
break;
} catch (Exception e) {
handleSoftFailure(e);
if (System.currentTimeMillis() - startTime > TIMEOUT) {
handleFailure(e);
break;
} else {
try {
Thread.sleep(WAIT_FOR_NEXT_TRY);
} catch (InterruptedException ex) {
}
}
}
}
函數返回正常參考版本:
@Override
public String doE() throws TestFailedException {
String result = null;
long startTime = System.currentTimeMillis();
while (true) {
try {
beforeOperation();
result = ((OtherTypeIDoNotOwn) element).doE();
handleSuccess();
break;
} catch (Exception e) {
handleSoftFailure(e);
if (System.currentTimeMillis() - startTime > TIMEOUT) {
handleFailure(e);
break;
} else {
try {
Thread.sleep(WAIT_FOR_NEXT_TRY);
} catch (InterruptedException ex) {
}
}
}
}
return result;
}
和功能返回類型參數的對象:
@Override
public T doF(String string) throws TestFailedException {
T result = null;
long startTime = System.currentTimeMillis();
while (true) {
try {
beforeOperation();
OtherTypeIDoNotOwn temp = ((OtherTypeIDoNotOwn) element).doF(string);
result = (T) elementClass.getDeclaredConstructor(Object.class).newInstance(temp);
handleSuccess();
break;
} catch (Exception e) {
handleSoftFailure(e);
if (System.currentTimeMillis() - startTime > TIMEOUT) {
handleFailure(e);
break;
} else {
try {
Thread.sleep(WAIT_FOR_NEXT_TRY);
} catch (InterruptedException ex) {
}
}
}
}
return result;
}
AWrapper也是如此,但是th Ë區別是:
- 構造具有存儲型的類參數
- 對象被轉換爲
IDoNotOwnThisType
代替OtherTypeIDoNotOwn
。此對象的功能也可能返回OtherTypeIDoNotOwn
。
IDoNotOwnThisType
是AWrapper
包裝的類型。
OtherTypeIDoNotOwn
是AType
包裝的類型。
然後,我們必須實現這些抽象類:
public class AssertingType extends AType<AssertingType> {
public AssertingType(Object element) {
super(element);
}
@Override
public void beforeOperation() {
//System.out.println("Asserting type before operation!");
}
@Override
public void handleSuccess() {
//TODO: add to log file and log to output
System.out.println("Asserting type success!");
}
@Override
public void handleFailure(Exception e) throws TestFailedException {
//TODO: add to log file, log to output and throw exception
System.out.println("Asserting type failure!");
e.printStackTrace();
throw new TestFailedException();
}
@Override
public void handleSoftFailure(Exception e) {
//TODO: add to log file, log to output
System.out.println("Asserting type soft failure!");
e.printStackTrace();
}
}
和:
public class AssertingWrapper extends AWrapper<AssertingType> {
public AssertingWrapper (Object driver) {
super(driver, AssertingType.class);
}
@Override
public void beforeOperation() {
//TODO
System.out.println("Asserting wrapper success!");
}
@Override
public void handleSuccess() {
//TODO: add to log file and log to output
System.out.println("Asserting wrapper success!");
}
@Override
public void handleFailure(Exception e) throws TestFailedException {
//TODO: add to log file, log to output and throw exception
System.out.println("Asserting wrapper failure!");
throw new TestFailedException();
}
@Override
public void handleSoftFailure(Exception e) {
//TODO: add to log file, log to output
System.out.println("Asserting wrapper soft failure!");
e.printStackTrace();
}
}
因此,我們可以使用它像:
AssertingWrapper wrapper = new AssertingWrapper(new IDoNotOwnThisType());
AssertingType type = wrapper.doC();
AssertingType type2 = type.doF();
輸出:
Asserting wrapper before operation!
doC
Asserting wrapper success!
Asserting type before operation!
doF
Asserting type success!
完整的工作代碼是在這裏: LIVE
的問題是,我一直寫while
,try
catch
等在AType
和AWrapper
,可我莫名其妙地減少代碼的重複?在這個例子中,我爲每個類提供了3個函數,但在我的真實代碼中,我有50多個方法。我可以以某種方式包裝這些功能,以便重複的部分不重複?
你能否給我們一個TL; DR這一切? –
@MikeNakis提供 – xinaiz
所以,我的解決方案是否適合你? –