简体   繁体   中英

Create an instance by a string name input

I am working on CS50 Android track Fiftygram app. My code is working but I don't like to see copy pasted codes.

Currently checking dropdown selected item name and using if/else if to call with representing instance of a Transformation. How can I directly call apply function with the string without using all these if and else ifs.

If I can find a way, I can fix some of the wording. For example, I can get rid of Transformation end of the strings and add it myself before calling the function.

public void applyFilter(View view) {
    if (filterList.getSelectedItem().toString() != null) {
        if (filterList.getSelectedItem().toString().equals("ToonFilterTransformation")) {
            apply(new ToonFilterTransformation());
        }
        else if (filterList.getSelectedItem().toString().equals("SepiaFilterTransformation")) {
            apply(new SepiaFilterTransformation());
        }
        else if (filterList.getSelectedItem().toString().equals("ContrastFilterTransformation")) {
            apply(new ContrastFilterTransformation());
        }
        else if (filterList.getSelectedItem().toString().equals("InvertFilterTransformation")) {
            apply(new InvertFilterTransformation());
        }
        else if (filterList.getSelectedItem().toString().equals("PixelationFilterTransformation")) {
            apply(new PixelationFilterTransformation());
        }
        else if (filterList.getSelectedItem().toString().equals("SketchFilterTransformation")) {
            apply(new SketchFilterTransformation());
        }
        else if (filterList.getSelectedItem().toString().equals("SwirlFilterTransformation")) {
            apply(new SwirlFilterTransformation());
        }
        else if (filterList.getSelectedItem().toString().equals("KuwaharaFilterTransformation")) {
            apply(new KuwaharaFilterTransformation());
        }
        else if (filterList.getSelectedItem().toString().equals("VignetteFilterTransformation")) {
            apply(new VignetteFilterTransformation());
        }
    }
}

public void apply(Transformation<Bitmap> filter) {
    if (original != null) {
        Glide
                .with(this)
                .load(original)
                .apply(RequestOptions.bitmapTransform(filter))
                .into(imageView);
    }
}

I suggest you to create a method and make filterList.getSelectedItem().toString() into a variable. Then make use of reflection in creating a class

something like

String item = filterList.getSelectedItem().toString();

apply(createInstance(item))
public Object createInstance(String item){
  Class classDefinition = Class.forName(item);
  return classDefinition.newInstance();
}

But you have to add further validations there if the item exists or not. But the idea is like that. Take advantage of reflection instead of using new keyword

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM