![](/img/trans.png)
[英]Adding strings to an Array in Abstract class A, from an extended class B in Java
[英]Decouple abstract class details from extended implementations
我有一个PluginClassLoader
,它是一个抽象类,可为项目的类加载器提供99%的功能。 我有2个子类( ServiceClassLoader
和ChannelClassLoader
),它们扩展了PluginClassLoader
,并且只不过是包装器和一些自定义的日志记录。 两种实现之间99%的逻辑是相同的。
然后,我有一个PluginManager
,它也是一个抽象类,具有2个扩展它的实现( ServiceManager
和ChannelManager
),这些实现是包装程序以及自定义日志记录和更方便的构造函数。
我遇到的麻烦是,在我的PluginManager
中,必须能够实例化ServiceClassLoader
或ChannelClassLoader
的新类加载器类型。 我试图避免将我的PluginManager
与当前的实现耦合在一起(即,我希望能够增加将来的实现,但又不更改PluginManager
的逻辑的灵活性),因此尝试避免传入一些Enum
并使用一些:
if (classLoaderType instanceof ClassLoaderType.SERVICE) {
// do logic for instantiating ServiceClassLoader
}
示例类层次结构:
public abstract class PluginManager {
// logic for managing plugins and when to load them
// ...
// somewhere deep in a loadPlugin(final File directory) method
pluginLoader = new PluginClassLoader(); // <-- not valid, can't instantiate
// an abstract class,
// and it's of the wrong type!
}
public abstract class PluginClassLoader extends URLClassLoader {
// class loader logic
}
public class ServiceManager extends PluginManager {
// wrapper for PluginManager with some customized logging
}
public class ServiceClassLoader extends PluginClassLoader {
// wrapper for PluginClassLoader with some customized logging
}
尝试避免做类似的事情:
public abstract class PluginManager {
private final PluginType pluginType;
public PluginManager(final PluginType pluginType) {
this.pluginType = pluginType;
}
// logic ...
// somewhere deep in the loadPlugin(final File directory) method
if (pluginType instanceof PluginType.SERVICE) {
pluginLoader = new ServiceClassLoader();
// more logic
} else if (plugintype instanceof PluginType.CHANNEL) {
pluginLoader = new ChannelClassLoader();
// more logic
}
}
您会错过enum
的惊人灵活性,它们本身就是完全被吹灭的对象,因此可以实现接口。 如果使枚举本身能够充当工厂,那么一切将变得简单。
这是将enum
用作工厂的极大简化的演示。
interface Loader {
public Plugin load();
}
enum PluginType implements Loader {
Service {
@Override
public Plugin load() {
return new ServiceClassLoader();
}
},
Channel {
@Override
public Plugin load() {
return new ChannelClassLoader();
}
};
}
public void loadPlugin(PluginType type) {
Plugin plugin = type.load();
}
public void test() {
loadPlugin(PluginType.Channel);
}
三种选择:
PluginManager
声明一个抽象的newClassLoader()
方法,在ServiceManager
中将其重写以返回新的ServiceClassLoader
等 PluginType
更改为Class<? extends ClassLoader>
Class<? extends ClassLoader>
,将其存储在字段中(例如classLoaderClass
),然后在需要时仅调用classLoader.newInstance()
PluginType
一个枚举(如果尚未枚举),该枚举具有自己的方法来创建新的ClassLoader
。 (不清楚是否由于其他原因是否需要PluginType
如果不需要,则不要。)
将抽象方法添加到PluginManager
以创建类加载器,然后根据需要调用它。 子类应重写该方法,并返回适当的子类:
public abstract class PluginManager {
public PluginManager() {
pluginLoader = MakeClassLoader();
}
...
protected abstract PluginClassLoader MakeClassLoader();
}
public class ServiceManager extends PluginManager {
...
protected abstract PluginClassLoader MakeClassLoader() {
return new ServiceClassLoader();
}
}
public class ChannelManager extends PluginManager {
...
protected abstract PluginClassLoader MakeClassLoader() {
return new ChannelClassLoader();
}
}
这实现了工厂方法设计模式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.