英文:
Pass in functionality to a method without any further changes to the class
问题
以下是翻译好的内容:
我有以下的逻辑,它在我迭代对象并替换字符串值(如果适用)时运行良好。
但我试图将其变得更通用:我希望“替换”逻辑来自外部。
这是因为我希望有灵活性,以根据需要添加更多的操作功能。
我不想每次都要进入这个类并修改它。相反,希望使其可配置。
是否有任何方法可以实现这一点?
例如,我可能想要另一个逻辑,如果值是字符串,我想将“hello”附加到字符串上。
我不想这样做:
private String addHello(String value) {
return value + "hello";
}
// 然后在解析方法中。
if (fieldValue instanceof String) {
field.set(obj, switchName((String) fieldValue));
field.set(obj, addHello((String) fieldValue)); // 插入新的hello逻辑
}
这意味着每次我都要修改这个类。并不完全遵循SOLID原则。
它应该是不可修改的。
我正在寻求如何将这个变为可配置,以便我可以停止触及以下实现,但仍然能够添加更多的逻辑到其中。
英文:
I have the following logic which works fine where I am iterating an object and replacing string values if applicable.
But I am trying to make this more generic: I want the replace
logic to come externally.
It is because I want the flexibility to be able to add on more manipulation functionality as needed.
I don't want to keep coming into this class and modify it each time. Instead looking to make it configurable.
Is there any approach I could take to achieve this?
For example I may want another logic where if the value is a string, I want to append "hello" to the string.
I don't want to do this:
private String addHello(String value) {
return value + "hello";
}
// then in the parse method.
if (fieldValue instanceof String) {
field.set(obj, switchName((String) fieldValue));
field.set(obj, addHello((String) fieldValue)); // new hello logic inserted
}
This would mean I am amending the class every time. Not exactly following SOLID principle.
It should be closed for modifications.
I am looking for advice on how I could turn this into being configurable so that I can stop touching the following implementation, but still be able to add on further logic to it.
import org.apache.commons.lang.reflect.FieldUtils;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.List;
import java.util.Map;
@Component
public class Helper {
@SuppressWarnings("unchecked")
public void parse(Object obj) throws IllegalAccessException {
if (obj == null) {
return;
}
for (Field field : obj.getClass().getDeclaredFields()) {
field.setAccessible(true);
int modifiers = field.getModifiers();
Object fieldValue = FieldUtils.readField(obj, field.getName(), true);
if (fieldValue instanceof String) {
field.set(obj, switchName((String) fieldValue));
}
else {
parse(fieldValue);
}
}
}
private String switchName(String value) {
return value.replace("apple", "orange");
}
}
答案1
得分: 1
只要替换引用String的字段,您可以传递一个 Function<String,String>
。
public void parse(Object obj, java.util.function.Function<String,String> replaceFn )
throws IllegalAccessException { ... }
如果您想更加通用,可以传递接受对象和字段的参数,并执行某些操作。将其定义为特定接口会更容易找到所有实现。
@FunctionalInterface
public interface IFieldReplacer {
public void accept(Object o, Field f) throws IllegalAccessException;
}
public class MyFieldReplacerA implements IFieldReplacer {
@Override
public void accept(Object o, Field f) throws IllegalAccessException {
// TODO 获取值,进行转换,然后设置它。
}
}
public void parse(Object obj, IFieldReplacer fieldReplacer ) {
...
}
这两种方法都允许调用者传递lambda表达式。
英文:
If you just want to replace fields referencing a String, you could pass in a Function<String,String>
.
public void parse(Object obj,
java.util.function.Function<String,String> replaceFn )
throws IllegalAccessException { ... }
If you want to be more general, you could pass in something that accepts an object and a field, and does something with it. Defining that as a specific interface makes it easier to find all implementations.
@FunctionalInterface
public interface IFieldReplacer {
public void accept(Object o, Field f) throws IllegalAccessException;
}
public class MyFieldReplacerA implements IFieldReplacer {
@Override
public void accept(Object o, Field f)
throws IllegalAccessException {
// TODO Get the value, transmogrify it, and set it.
}
}
public void parse(Object obj, IFieldReplacer fieldReplacer ) {
...
}
Both of these allow the caller to pass in a lambda expression.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论