摘要中的可选方法实现 class
Optional method implementation in an abstract class
我正在研究一些框架,我得到了一个摘要class,应该实现它。
现在我得到了一些用户应该能够配置的其他东西,但它是可选的。
所以不是抽象方法:
public abstract class AbstractModule {
public void doSomething() {
if (logMessage() != null)
System.out.println(logMessage());
doStuff();
}
protected abstract String logMessage(); // I'm optional
protected abstract void doStuff();
}
我想只检查一个接口实现:
public interface Log {
String logMessage();
}
public abstract class AbstractModule {
public void doSomething() {
if (this instanceof Log) {
if (((Log) this).logMessage() != null)
System.out.println(((Log) this).logMessage());
}
doStuff();
}
protected abstract void doStuff();
}
因此,如果有人使用 Log 接口实现 AbstractModule,它也会显示消息。我看到的对实施者的好处:她不需要关心实施 logMessage(),就像在第一个示例中那样。这是一种有效的方法还是应该采用不同的方法?
提前致谢!
此致
达到 instanceof
有点代码味;通常有更好的方法。
我的第一直觉是在基 class:
中有一个 no-op 方法
class AbstractModule {
final void doSomething() {
maybeLogMessage();
}
void maybeLogMessage() {}
}
这显然什么也没做;但是你可以在 subclass:
中覆盖
class Subclass extends AbstractModule {
@Override void maybeLogMessage() {
System.out.println("The message");
}
}
这将打印消息。
如果你不想在所有子class中重复System.out.println
,你可以return方法中的一个特殊值来表明它不应该记录。例如,您可以要求字符串为 non-empty:
class AbstractModule {
final void doSomething() {
String message = logMessage();
if (!message.isEmpty()) { System.out.println(message); }
}
String logMessage() { return ""; }
}
class Subclass extends AbstractModule {
@Override String logMessage() {
return "The message";
}
}
我会让 Logger 成为您模块的一个组件,并在抽象 class 中定义一个默认的 no-op 记录器。这样你就可以摆脱 instanceof
并仍然保持灵活性。
interface Log {
void logMessage();
}
public abstract class AbstractModule {
protected Log log;
public AbstractModule(){
this.log = () -> {};
}
public AbstractModule(Log log){
this.log = log;
}
public void doSomething() {
log.logMessage();
doStuff();
}
protected abstract void doStuff();
}
这里是一个例子 class 扩展 AbstractModule
:
public class Module extends AbstractModule{
public Module(){
super(() -> System.out.println("message"));
}
@Override
protected void doStuff() {
// do stuff
}
}
如果你想暴露记录器,你可以在抽象class中为记录器定义一个getter-method:
public Log getLogger(){
return log;
}
由于此问题已被标记为 java-8
,另一种解决方案是使用 interface
和 default
方法:
public interface Module {
public default void doSomething() {
if (logMessage() != null)
System.out.println(logMessage());
doStuff();
}
public default String logMessage() { return null; } // I'm optional
public void doStuff();
}
用法:
class NoLogModule implements Module {
@Override
public void doStuff() { }
}
class LogModule implements Module {
@Override
public void doStuff() { }
@Override
public String logMessage() { return "Message "; }
}
使用这种方法而不是 Abstract class 的一个优点是您的 class 现在可以从另一个 class 自由扩展.这种方法的一个缺点是您无法阻止某人 覆盖 doSomething
方法(根据您的代码,您似乎并不关心这个)
我正在研究一些框架,我得到了一个摘要class,应该实现它。
现在我得到了一些用户应该能够配置的其他东西,但它是可选的。
所以不是抽象方法:
public abstract class AbstractModule {
public void doSomething() {
if (logMessage() != null)
System.out.println(logMessage());
doStuff();
}
protected abstract String logMessage(); // I'm optional
protected abstract void doStuff();
}
我想只检查一个接口实现:
public interface Log {
String logMessage();
}
public abstract class AbstractModule {
public void doSomething() {
if (this instanceof Log) {
if (((Log) this).logMessage() != null)
System.out.println(((Log) this).logMessage());
}
doStuff();
}
protected abstract void doStuff();
}
因此,如果有人使用 Log 接口实现 AbstractModule,它也会显示消息。我看到的对实施者的好处:她不需要关心实施 logMessage(),就像在第一个示例中那样。这是一种有效的方法还是应该采用不同的方法?
提前致谢!
此致
达到 instanceof
有点代码味;通常有更好的方法。
我的第一直觉是在基 class:
中有一个 no-op 方法class AbstractModule {
final void doSomething() {
maybeLogMessage();
}
void maybeLogMessage() {}
}
这显然什么也没做;但是你可以在 subclass:
中覆盖class Subclass extends AbstractModule {
@Override void maybeLogMessage() {
System.out.println("The message");
}
}
这将打印消息。
如果你不想在所有子class中重复System.out.println
,你可以return方法中的一个特殊值来表明它不应该记录。例如,您可以要求字符串为 non-empty:
class AbstractModule {
final void doSomething() {
String message = logMessage();
if (!message.isEmpty()) { System.out.println(message); }
}
String logMessage() { return ""; }
}
class Subclass extends AbstractModule {
@Override String logMessage() {
return "The message";
}
}
我会让 Logger 成为您模块的一个组件,并在抽象 class 中定义一个默认的 no-op 记录器。这样你就可以摆脱 instanceof
并仍然保持灵活性。
interface Log {
void logMessage();
}
public abstract class AbstractModule {
protected Log log;
public AbstractModule(){
this.log = () -> {};
}
public AbstractModule(Log log){
this.log = log;
}
public void doSomething() {
log.logMessage();
doStuff();
}
protected abstract void doStuff();
}
这里是一个例子 class 扩展 AbstractModule
:
public class Module extends AbstractModule{
public Module(){
super(() -> System.out.println("message"));
}
@Override
protected void doStuff() {
// do stuff
}
}
如果你想暴露记录器,你可以在抽象class中为记录器定义一个getter-method:
public Log getLogger(){
return log;
}
由于此问题已被标记为 java-8
,另一种解决方案是使用 interface
和 default
方法:
public interface Module {
public default void doSomething() {
if (logMessage() != null)
System.out.println(logMessage());
doStuff();
}
public default String logMessage() { return null; } // I'm optional
public void doStuff();
}
用法:
class NoLogModule implements Module {
@Override
public void doStuff() { }
}
class LogModule implements Module {
@Override
public void doStuff() { }
@Override
public String logMessage() { return "Message "; }
}
使用这种方法而不是 Abstract class 的一个优点是您的 class 现在可以从另一个 class 自由扩展.这种方法的一个缺点是您无法阻止某人 覆盖 doSomething
方法(根据您的代码,您似乎并不关心这个)