有没有办法在运行时使用Java分配类?

时间:2015-09-11 11:38:12

标签: java class dynamic reflection

由于我现在正在重构我的代码,我试图首先找出可能的代码重复。 作为一个可靠的副本,我看到基本上读取文件的2种方法:一种来自FTP,另一种来自本地文件结构。问题是,他们当然使用不同的类来实现相同的事情。变量directoryListing是棘手的。

readLogs(boolean useFTP){
// directory Listing of course needs to be of a different type here or not being declared at all 
    File[] directoryListing;
    File dir = Settings.getInputfolder();
    if(useFTP){
            // ftp implementation
            client = new FTPClient();               
            client.connect(Settings.getFtpHost());
            client.enterLocalPassiveMode();
            client.login(Settings.getFtpLoginname(), Settings.getFtpPassword());
            client.setFileType(FTPClient.BINARY_FILE_TYPE);

            //directoryListing should be of type FTPFile[] here
            directoryListing = client.listFiles(Settings.getInputfolder().toString());
    else{
        //directoryListing should be of type File[] in this case
        directoryListing = dir.listFiles();
    }
    if (directoryListing == null) {
            log.error("Input-folder not found:" + dir.getAbsolutePath());
    }
    //I want to be able to iterate - here myFolder might be of type File oder FTPFile
    for (Object myFolder : directoryListing) {
    ...
    ...
    }
}

我稍后在代码中使用的唯一方法在File和FTP文件上都有完全相同的签名:
    的getName()
    ISFILE()
    的isdirectory()
    listFiles()
我已经使用了反射,例如

Method getFolderNameMethod = myFolder.getClass().getMethod("getName");
String name = (String) getFolderNameMethod.invoke(myFolder);

以什么方式可以实现directoryListing变量的某种动态声明?

非常感谢您提前的时间和建议! :d

2 个答案:

答案 0 :(得分:1)

我过去使用过apache-commons-vfs:

http://commons.apache.org/proper/commons-vfs/

如果您不想使用lib,可以创建一个接口及其两个实现,但VFS将为您提供更多支持的文件系统,从长远来看可能更容易维护。

我确定还有其他人,但我从来不需要除了apache之外的其他任何东西,所以我不能和他们说话。

编辑:

根据你的评论,我会为一家工厂创建一个类似于:

的工厂
public class FSFactory{
  public static IFSInteface getInterfaceFor(FSType t){
     if(FSType.FTP.equals(t)){
        return new FtpFileGetter();
     } else if (FSType.LOCAL.equals(t)){
        return new FSFileGetter();
     }
  }
}

代码未经过测试,但这就是我处理这类内容的方式。

答案 1 :(得分:1)

使用策略和适配器模式:

首先定义公共接口

@app.route('/register', methods=['PUT'])
def register():
    username = request.form.get('username')
    password = request.form.get('password')
    if username is None or password is None:
        abort(400)  # missing parameters

    user = User.query.filter_by(username=username).first()
    if user:
        abort(400)  # user exists
    else:
        user = User(user=user)
        user.hash_password(password)
        db.session.add(user)
        db.session.commit()

        # How do we generate a token?
        redirect("login_success", code=307)

@app.route("login_success", methods=["GET", "POST"])
@jwt_required()
def login_success():
    return "Redirected Success!"

然后创建两个适配器(一个用于File,一个用于FTPFile)

interface VirtualFile {
  /*
  getName()
  isFile()
  isDirectory()
  listFiles()
  */
}

然后重构class FileAdapter implements VirtualFile { // delegates every method to the wrapped file } class FTPFileAdapter implements VirtualFile { // delegates every method to the wrapped ftp file }

readLogs

这可以将所有问题分开并另外: - 再也不用了 - 没有铸造 - 没有反思 - 更短的方法/类