[英]Java: Two classes with nearly identical methods using two different enums; possible to avoid redundancy? (static methods everywhere)
[英]Java design pattern for two classes sharing identical and similar but different methods
假设我的应用程序有一些实现为ClassA
和ClassB
。 两者有一些相似之处,但也有不同之处。
start()
方法,方法签名相同,但实现不同。process()
方法。log()
方法,即代码完全相同。public class ClassA {
public String start(String s1, String s2) {
startImplementation();
return someString;
}
public String process(String s) {
processingImplementation();
return processedString;
}
private String log(String s) {
logImplementation();
return sharedString;
}
}
public class ClassB {
public String start(String s1, String s2) {
otherStartImplementation();
return someString;
}
public String process(Long l) {
otherProcessingImplementation();
return processedString;
}
private String log(String s) {
logImplementation();
return sharedString;
}
}
我在思考“设计模式”如何以更通用的方式组织它时遇到了麻烦。 从 3 开始,我可以轻松地将此方法移动到ClassA
和ClassB
扩展的超类。 但是我将/如何设计应用程序以便 1. 和 2. 也被考虑在内?
项目 1. 对我来说听起来有点像一个接口,但我不知道如何将它与项目 3 的超类结合起来。那么项目 2 呢?
我会这样设计,以便class A
和class B
扩展一个通用抽象类,并为process
方法的参数类型提供一个类型参数。
public abstract class BaseClass<T> {
public abstract String start(String s1, String s2);
public abstract String process(T value);
protected final String log(String s) {
// shared log implementation
}
}
public class A extends BaseClass<String> {
@Override
public String start(String s1, String s2) {
// A.start implementation
}
@Override
public String process(String s) {
// A.process implementation
}
}
public class B extends BaseClass<Long> {
@Override
public String start(String s1, String s2) {
// B.start implementation
}
@Override
public String process(Long l) {
// B.process implementation
}
}
在 Java 9+ 中,您可以改为使用通用public interface Base<T>
而不是抽象类,通过为log
提供默认实现。 但是,这不允许您使log
只有实现类可以访问,并且它不会阻止子类覆盖log
。
如何使用组合而不是继承? start
和process
的实现可以由如下示例中的函数提供:
import java.util.function.BiFunction;
import java.util.function.Function;
class X<T> {
public String start(BiFunction<String, String, String> f, String s1, String s2) {
return f.apply(s1, s2);
}
public String process(Function<T, String> f, T t) {
return f.apply(t);
}
// example
public static void main(String[] args) {
X<String> xString = new X();
xString.start((s1, s2) -> s1 + s2, "a", "b");
X<Long> xLong = new X();
xLong.process((t) -> { Long tt = t * 2;return tt.toString(); }, 4L);
}
}
与前面的示例相同,但在构造函数中提供了实现,并使用函数式接口而不是 lambdas。
import java.util.function.BiFunction;
import java.util.function.Function;
class StartFunctionExample implements BiFunction<String, String, String> {
@Override
public String apply(String s1, String s2) {
return s1 + s2;
}
}
class ProcessFunctionExample implements Function<Long, String> {
@Override
public String apply(Long t) {
Long tt = (t * 2);
return tt.toString();
}
}
class Z<T> {
private final BiFunction<String, String, String> startFunction;
private final Function<T, String> processFunction;
public Z(
BiFunction<String, String, String> startFunction,
Function<T, String> processFunction
) {
this.startFunction = startFunction;
this.processFunction = processFunction;
}
public String start(String s1, String s2) {
return startFunction.apply(s1, s2);
}
public String process(T t) {
return processFunction.apply(t);
}
// example
public static void main(String[] args) {
Z<Long> xLong = new Z(new StartFunctionExample(), new ProcessFunctionExample());
xLong.start("a", "b"); // ab
xLong.process(7L); // 14
}
}
让不同的类实现日志记录,处理可以通过实现服务接口的类来完成:
interface Processable {
String start(String s1, String s2);
process(String s);
}
class LogDecorator {
private Processable p;
public LogDecorator(Processable p) {
this.p = p;
}
public String start(String s1, String s2) {
p.start(s1, s2);
}
public String process(String s) {
p.process();
}
protected final String log(String s) {
// logging
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.