Design Pattern to Reduce Redundancy

I am currently developing a class that heavily uses reflection by manipulating declared fields. Therefore, many methods have something in common from the point of view of their body, which (I hope) is illustrated by this java code:

import java.lang.reflect.Field; public class foo { public void foo1(/* arguments1 */) { for (Field f : getClass().getDeclaredFields()) { // do some stuff using arguments1 } } public void foo2(/* arguments2 */) { for (Field f : getClass().getDeclaredFields()) { // do some stuff using arguments2 } } public void foo3(/* arguments3 */) { for (Field f : getClass().getDeclaredFields()) { // do some stuff using arguments3 } } //and so on... } 

Depending on how many methods this class finally contains, can this be considered a design error? If I want to use getFields() instead of getDeclaredFields() , for example, I will need to replace each occurrence of getDeclaredFields() . This is not like good programming practice. In my case, this may not be a very realistic scenario, but for fun, I would like to know if there is a design template or concept that solves this problem.

[EDIT]

To avoid additional misunderstandings: the operations inside the loop depend on the arguments given by foo1, foo2, etc., and these arguments are not always the same for each method. I have illustrated this fact poorly, sir. I improved this code to demonstrate it better.

+4
source share
3 answers

You might want to define an interface for the loop body:

 interface FieldOperation { void doSomeStuff(Field f); } 

Then, instead of foo1 , foo2 and foo3 you can write one looping method:

 public void foo(/* arguments */, FieldOperation op) { for (Field f : getClass().getDeclaredFields()) { op.doSomeStuff(f); } } 

Then you can create several FieldOperation objects:

 FieldOperation foo1Operation = new FieldOperation() { void doSomeStuff(Field f) { // do some stuff that used to be in foo1() } } // etc. 

This scales well and separates the logic of which fields are available for the operation that you want to perform in each field.

EDIT If each foo* requires a different set of arguments, I would suggest packing them as classes:

 class Foo1Args { . . . } class Foo2Args { . . . } class Foo3Args { . . . } 

Then you can make your general interface:

 interface FieldOperation<T> { void doSomeStuff(Field f, T args); } 

and define foo as a generic method:

 public <T> void foo(T args, FieldOperation<T> op) { for (Field f : getClass().getDeclaredFields()) { op.doSomeStuff(f, args); } } 
+5
source

To reuse logic to search for fields, you can externalize it to a separate method or field:

 public class foo { private final Field[] fields = getClass().getDeclaredFields(); public void foo1(/* arguments */) { for (Field f : fields) { // do some stuff } } public void foo2(/* arguments */) { for (Field f : fields) { // do some stuff } } public void foo3(/* arguments */) { for (Field f : fields) { // do some stuff } } } 
0
source

Instead of creating a new field that needs to be filtered out from other methods, why not create a method to get the fields:

 public class foo { private Field[] getDeclaredFields() { return getClass().getDeclaredFields(); } public void foo1(/* arguments */) { for (Field f : getDeclaredFields()) { // do some stuff } } public void foo2(/* arguments */) { for (Field f : getDeclaredFields()) { // do some stuff } } public void foo3(/* arguments */) { for (Field f : getDeclaredFields()) { // do some stuff } } } 
0
source

Source: https://habr.com/ru/post/1433270/


All Articles