我正在尝试向代码中添加一些日志。
添加了一个新的类DataEntry:
class DataEntry
{
private final String name;
private final List<String> data;
public String getName()
{
return name;
}
public List<String> getData()
{
return data;
}
DataEntry(String name, List<String> data)
{
this.name = name;
this.data = data;
}
}
现在,我在另一个类中有一个方法需要传递一些参数,因此我在调用该类并对其进行初始化。
class Information
{
protected void logData()
{
List<DataEntry> output = new ArrayList<>();
// I have 10-12 like this entries, is there a better way to do this
//Also is the tight coupling incorrect ? Any other way should i approach or is it fine ?
DataEntry id = new DataEntry("id",Arrays.asList(getid()));
DataEntry name = new DataEntry("name",Arrays.asList("abc","xyz"));
//Same will need to add 20-30 entries here
output.add(id );
output.add(name );
}
}
问题出在logData方法中,我有20-30个参数,所以有没有更好的方法来调用DataEntry类并将其添加到列表中?
答案 0 :(得分:-1)
您可以使用此方法:
void log(String name, String... data) {
DataEntry dataEntry = new DataEntry(name, Arrays.asList(data));
// log your dataEntry
}
或者如果您真的想要列表:
void makeAndLog(List<DataEntry> list, String name, String... data) {
DataEntry dataEntry = new DataEntry(name, Arrays.asList(data));
list.add(dataEntry);
}
void logData() {
List<DataEntry> list;
makeAndLog(list, "id1", "1", "2");
makeAndLog(list, "id5", "3", "4");
// log your list
}
答案 1 :(得分:-1)
所以我提出了这个解决方案,但是它在所有情况下都不能使用,因为它有局限性和某些规则
主要思想是如何无需手写就可以获取所有字段,现在您可以根据需要使用或重新设计它(从构造函数而不是方法中反映出来……)
在发布解决方案之前,我建议您针对这种用例使用AOP(aspect4j)更好。
我首先定义了一个记录器以类为中心的枚举,因此对于每个类,您都应该定义一个记录器逻辑,但是您可以使用我编写的一个通用逻辑。
这是经过简单测试的代码
我定义一个POJO,在其中包装参数或将其用作方法签名
public class User {
private String name;
private String username;
private String email;
public User(String name, String username, String email) {
super();
this.name = name;
this.username = username;
this.email = email;
}
public void mutate(String name, String username) {
System.out.println("this is a mutation");
}
public void reflectAll(String name, String username, String email) {
System.out.println("this is a full reflection");
}
public String getEmail() {
return email;
}
public String getName() {
return name;
}
public String getUsername() {
return username;
}
public void setEmail(String email) {
this.email = email;
}
public void setName(String name) {
this.name = name;
}
public void setUsername(String username) {
this.username = username;
}
}
您添加的数据条目保持不变,是toString
替代项可以在控制台上打印
public class DataEntry {
private final String name;
private final List<String> data;
public String getName() {
return name;
}
public List<String> getData() {
return data;
}
DataEntry(String name, List<String> data) {
this.name = name;
this.data = data;
}
@Override
public String toString() {
return "DataEntry [name=" + name + ", data=" + data + "]";
}
}
我使用枚举作为记录器,首先也许您会看到一种使用枚举的新方法(您可以使用一个类来做同样的事情),但是我说可能您会从中学习新的东西
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
public enum DataEntryLogger {
USER_CLASS{
@Override
List<DataEntry> log(Object o,String methodName) {
List<DataEntry> userDataEntries = new ArrayList<DataEntry>();
if( o instanceof User) {
User toLog = (User) o;
Optional<Method> oInvokedMethod = Arrays.asList(toLog.getClass().getMethods()).stream().filter((m) -> m.getName().equals(methodName)).findFirst();
oInvokedMethod.ifPresent((invokedMethod)-> {
for(Parameter p : invokedMethod.getParameters()) {
System.out.println(p.getName());
try {
Field f = o.getClass().getDeclaredField(p.getName());
f.setAccessible(true);
userDataEntries.add(new DataEntry(p.getName(), Arrays.asList(""+f.get(o))));
System.out.println(f.get(o));
} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException
| SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
return userDataEntries;
}
},
GENERIC{
@Override
List<DataEntry> log(Object o,String methodName) {
List<DataEntry> dataEntries = new ArrayList<DataEntry>();
Optional<Method> oInvokedMethod = Arrays.asList(o.getClass().getMethods()).stream().filter((m) -> m.getName().equals(methodName)).findFirst();
oInvokedMethod.ifPresent((invokedMethod)-> {
for(Parameter p : invokedMethod.getParameters()) {
System.out.println(p.getName());
try {
Field f = o.getClass().getDeclaredField(p.getName());
f.setAccessible(true);
dataEntries.add(new DataEntry(p.getName(), Arrays.asList(""+f.get(o))));
System.out.println(f.get(o));
} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException
| SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
return dataEntries;
}
};
abstract List<DataEntry> log(Object o,String methodName);
}
最后这是一个小用例,如何使用它
public class Information {
public static void main(String[] args) {
DataEntryLogger logger = DataEntryLogger.USER_CLASS;
User user = new User("taleb", "mhaleb", "talcorpdz@gmail.com");
System.out.println("mutate methode invoked : " + logger.log(user, "mutate"));
System.out.println("--------------------------------------------");
System.out.println("--------------------------------------------");
showUser(user);
System.out.println("--------------------------------------------");
System.out.println("--------------------------------------------");
logger = DataEntryLogger.GENERIC;
user = new User("genric", "genericUser", "generic@gmail.com");
System.out.println("mutate methode invoked : " + logger.log(user, "mutate"));
System.out.println("--------------------------------------------");
System.out.println("--------------------------------------------");
showUser(user);
}
public static void showUser(User u) {
System.out.println("case of object used as dto");
DataEntryLogger logger = DataEntryLogger.USER_CLASS;
System.out.println("showUser methode invoked : " + logger.log(u, "reflectAll"));
}
}
您应在Java编译器部分的项目设置中启用“存储有关方法参数的信息(可通过反射使用)”,这对于解析参数名称是必不可少的
参数名称应与字段相同
您可以根据需要编辑此作品并使其更加灵活