在不以任何方式修改A
、B
或C
的情况下,如何使类A
、B
、C
具有功能F,然后将类D
添加到bin/
并获得与F不同的功能?
我在《我的世界》的ModLoader中看到过这一点。使用ModLoader,您可以将类从ModLoader复制到Minecraft。然后,你可以简单地将一个以"mod_"开头的新类放入Minecraft jar中,它会为游戏添加新内容。在任何时候都没有任何类直接引用您的"mod_Foobar"类。
一个小的工作示例,并链接到任何进一步的阅读是可取的。
public class Reflection {
public void sayHello(String theClass){
//Since Mod classes are in package 'mod', we precede their name accordingly.
Class aClass = Class.forName("mod." + theClass);
aClass.getMethod("sayHi").invoke(aClass.newInstance());
}
public static void main(String[] args) {
//Get a list of the compiled classes in the 'mod' folder
String path = "./bin/mod";
String fileName;
File folder = new File(path);
List<File> fileList = Arrays.asList(folder.listFiles());
//Iterate through the list of classes to invoke their methods
Iterator<File> it = fileList.iterator();
while(it.hasNext()){
fileName = it.next().getName();
//When invoking the sayHello method, we remove the file extension
new Reflection().sayHello(fileName.replace(".class", ""));
}
}
}
ModA类:
public class ModA {
public void sayHi(){
System.out.println("Hi! I'm ModA.");
}
}
ModB:类
public class ModB {
public void sayHi(){
System.out.println("Hi! I'm ModB.");
}
}
请注意:
- 为了澄清这个例子,我删除了一些必要的异常处理
- Mod类位于一个名为"Mod"的包中。编译后,它们出现在bin/mod中。可能有一种更清洁的方式来扫描它们
- Mod类被编译、打包到一个jar中并包含在构建路径中
类路径用于加载类,并且是有序的,因此如果将类放在原始类之前,则将加载您的类,而不是原始类。
我想这一切都是为了应用基本的OO原则。
简单的继承可以让你实现多态性。在设计良好的系统中,这是将新行为引入系统的良好起点。
策略模式是工具箱中的另一种软件设计模式,可以在运行时选择算法的行为。
工厂模式(与反射和上面提到的模式相结合)可以创建一个系统,在这个系统中,您可以将类"放入"现有系统中,以便在不更改其核心的情况下添加新功能。
您还可以在启动时执行类路径扫描以查找有趣的(带注释的)类,从而修改运行时行为。
我相信MindCraft是一个设计良好的系统,它应用了比这里描述的模式多得多的模式。
最终,这一切都归结为良好的设计和在正确的地方应用正确的模式。