2017-01-09 3 views
0

I имеют следующую структуру:Как добавить абстрактный класс посередине с вызовом функции с помощью java?

public abstract class BaseCall<T> implements Callable<T> { 

    public abstract T innerCall(); 

    protected Structure getProxy() { 
     return SomeStructure; 
    } 
} 

и по крайней мере 4-х классов, которые выглядят так:

public class GetXCall extends BaseCall<Set<String>> { 

    private final Credentials credentials; 

    public GetXCall (Credentials credentials) { 
     this.credentials = credentials; 
    } 

    @Override 
    public Set<String> innerCall() { 
     return getProxy().getXfromVC(credentials); 
    } 

} 

public class GetYCall extends BaseCall<Set<String>> { 

    private final Credentials credentials; 

    public GetYCall (Credentials credentials) { 
     this.credentials = credentials; 
    } 

    @Override 
    public Set<String> innerCall() { 
     return getProxy().getYfromVC(credentials); 
    } 
} 

Я пытаюсь выяснить, как сделать его красивее и добавить еще один абстрактный класс в средний, так что я могу просто передать функции getYfromVC или getXfromVC и абстрактный класс будет называть что-то вроде:

getProxy()._____(credentials) 

Это то, что я пытался, но это, кажется, не работает, как я не могу использовать run внутри

public abstract class RunVcTask<T> extends BaseCall<T> { 

    private final Credentials credentials; 

    public RunVcTask(Credentials credentials) { 
     this.credentials = credentials; 
    } 

    public abstract T run(); 

    @Override 
    public T innerCall() { 
     return getProxy().run(credentials); //HERE the run can't work 
    } 
} 

Как InnerCall не всегда использует учетные данные, я не могу изменить его abstract innerCall(Credentials c)

может кто-то посоветуйте, есть ли хороший способ сделать это? (я в настоящее время с помощью Java 7)

+0

вы будете st должен называть его getfromVC() –

+0

что? не могли бы вы объяснить. getProxy() не может вызвать «run» – user1386966

+0

. Ваши классы уже очень просты, непонятно, почему вам нужно упростить его. –

ответ

1

Если придерживаться наследования, не существует упрощение возможно за

public abstract class BaseCall<T> implements Callable<T> { 

    public abstract T innerCall(); 

    protected Structure getProxy() { 
     return SomeStructure; 
    } 
} 
public abstract class RunVcTask<T> extends BaseCall<T> { 

    private final Credentials credentials; 

    public RunVcTask(Credentials credentials) { 
     this.credentials = credentials; 
    } 

    public abstract T actualOp(Structure proxy, Credentials credentials); 

    @Override 
    public T innerCall() { 
     return actualOp(getProxy(), credentials); 
    } 
} 

public class GetXCall extends RunVcTask<Set<String>> { 
    public GetXCall(Credentials credentials) { 
     super(credentials); 
    } 

    @Override 
    public Set<String> actualOp(Structure proxy, Credentials credentials) { 
     return proxy.getXfromVC(credentials); 
    } 
} 
public class GetYCall extends RunVcTask<Set<String>> { 
    public GetYCall(Credentials credentials) { 
     super(credentials); 
    } 

    @Override 
    public Set<String> actualOp(Structure proxy, Credentials credentials) { 
     return proxy.getXfromVC(credentials); 
    } 
} 

Лучший подход использует делегации:

public class RunVcTask<T> extends BaseCall<T> { 
    interface ActualTask<T> { 
     T actualOp(Structure proxy, Credentials credentials); 
    } 
    enum BuiltIn implements ActualTask<Set<String>> { 
     GetX { 
      public Set<String> actualOp(Structure proxy, Credentials credentials) { 
       return proxy.getXfromVC(credentials); 
      } 
     }, 
     GetY { 
      public Set<String> actualOp(Structure proxy, Credentials credentials) { 
       return proxy.getYfromVC(credentials); 
      } 
     }, 
    } 

    private final Credentials credentials; 
    private final ActualTask<T> delegate; 

    public RunVcTask(Credentials credentials, ActualTask<T> task) { 
     this.credentials = credentials; 
     this.delegate = task; 
    } 

    @Override 
    public T innerCall() { 
     return delegate.actualOp(getProxy(), credentials); 
    } 
} 

Здесь , не требуется специальный подкласс для GetX, GetY и т. д., вы можете создать такой вызов через

BaseCall<Set<String>> getXInstance = new RunVcTask<>(credentials, RunVcTask.BuiltIn.GetX); 
BaseCall<Set<String>> getYInstance = new RunVcTask<>(credentials, RunVcTask.BuiltIn.GetY); 

поэтому код специализации конкретной функции сводится к четырем линиям в пределах BuiltInenum. Только действия с одним и тем же типом возвращаемого типа могут быть агрегированы в пределах такого enum, поэтому вам придется использовать несколько enum s для разных типов (их не нужно встраивать в RunVcTask) или вместо этого использовать анонимные внутренние классы больше:

BaseCall<Set<String>> getXInstance = new RunVcTask<>(credentials, 
    new RunVcTask.ActualTask<Set<String>>() { 
     public Set<String> actualOp(Structure proxy, Credentials credentials) { 
      return proxy.getXfromVC(credentials); 
     } 
    }); 
BaseCall<Set<String>> getYInstance = new RunVcTask<>(credentials, 
    new RunVcTask.ActualTask<Set<String>>() { 
     public Set<String> actualOp(Structure proxy, Credentials credentials) { 
      return proxy.getYfromVC(credentials); 
     } 
    }); 

вы можете также использовать анонимные внутренние классы RunVcTask в примере наследования, сокращение кода в одинаковой степени, но подход делегация также предоставляет дорожную карту для Java 8, как только вы в состоянии для переключения:

BaseCall<Set<String>> getXInstance = new RunVcTask<>(credentials, Structure::getXfromVC); 
BaseCall<Set<String>> getYInstance = new RunVcTask<>(credentials, Structure::getYfromVC); 
Смежные вопросы