Variable Assignment Request Object Design

I have several classes that are not allowed to change each other's fields, but instead need to request a change by adding the request object to the main class queue. The main class, at the end of each cycle, will execute the requested changes.

public class Main {

    public static ClassA a = new ClassA();
    public static ClassB b = new ClassB();

    private static List<Request> requestQueue = new ArrayList<Request>(); // List holds all requests

    public static void main(String args[]) {
        while (true) {
            a.tick();
            b.tick();
            for (Request r : requestQueue) {
                r.field = r.value; // All requests are fulfilled 
            }
            requestQueue.clear();
        }
    }

    public static <ValueType> void addModificationRequest(ValueType field,
            ValueType value) {
        requestQueue.add(new Request<ValueType>(field, value));
    }
}

// Request Object
public class Request<ValueType> {

    ValueType field;
    ValueType value;

    public Request(ValueType field, ValueType value) {
        this.field = field;
        this.value = value;
    }
}

// Classes
public class ClassA {
    String name = "A";

    public void tick() {
        Main.addModificationRequest(Main.b.name, "NewNameB"); // Try to change b name
    }
}

public class ClassB {
    String name = "B";

    public void tick() {
        // Nothing
    }
}

I know the code is dirty, but its the easiest way I've been thinking about so far. Does anyone know of any good design patterns that can make this a simpler and more reliable way? (Note: I must have it this way, there is no way to allow classes to directly modify each other.)

: . , - , .

: , ! . , , . .

+3
3

, , , , .

set, , . , , , .

public class DelayedModificationField<T> {
    private T field;
    private T newValue;
    public T get() { return field;}
    public delayedSet(T value) {
        if (newValue != null) throw new ConcurrentModificationException("error");
        newValue = value;
    }
    public void performSet() {
        field = newValue;
        newValue = null;
    }

public ExampleClass {
    private DelayedModificationField<String> myField = new DelayedModificationField<String>();
    public void setMyField(String s) { myField.delayedSet(s);}
    public String getMyField() { return myField.get();}
    public void performSet() { myField.performSet();}
}

, , . .

+1

. , Modifiable void setField(ValueType newValue). ClassA ClassB Modifiable. , Request Modifiable ValueType ValueType. :

for (Request r : requestQueue) {
    r.modifiable.setField(r.value);
}

EDIT:

, :

interface Modifiable {
    void setName(String newName);
    void setAge(Integer newAge); // I wish
}

abstract class Request<ValueType> {
    Modifiable object;
    ValueType value;

    public Request(Modifiable object, ValueType value) {
        this.object = object;
        this.value = value;
    }

    abstract void execute();
}

class RequestNameChange extends Request<String> {
    public RequestNameChange(Modifiable object, String name) {
        super(object, name);
    }

    void execute() {
        object.setName(name);
    }
}

// etc.

, , , .

0

"" - " , ", " ".

:

public static class Main {

    public static ClassA a = new ClassA();
    public static ClassB b = new ClassB();

    private static List<Runnable> requestQueue = new ArrayList<Runnable>(); // List holds all requests

    public static void main(String args[]) {
        while (true) {
            a.tick();
            b.tick();
            for (Runnable r : requestQueue) {
                r.run(); // All requests are fulfilled 
            }
            requestQueue.clear();
        }
    }

    public static void addModificationRequest(Runnable runnable) {
        requestQueue.add(runnable);
    }
}

addModificationRequest :

Main.addModificationRequest(new Runnable() {
    public void run() {
        Main.b.name = "NewNameB";
    }
});

, ConcurrentModificationException, addModificationRequest , foreach. synchronized addModificationRequest + , .

Edit:

, , :

interface FieldUpdater extends Runnable
{
    Field getField();
}

static class Main
{

    public static ClassA a = new ClassA();
    public static ClassB b = new ClassB();

    private static List<FieldUpdater> requestQueue = new ArrayList<FieldUpdater>(); // List holds all requests

    private static Set<Field> seenBefore = new HashSet<Field>();

    public void main(String args[])
    {
        while (true)
        {
            a.tick();
            b.tick();
            for (FieldUpdater r : requestQueue)
            {
                if (seenBefore.contains(r.getField()))
                {
                    continue; // Or do something else specific
                }
                seenBefore.add(r.getField());
                r.run();
            }
            requestQueue.clear();
        }
    }

    public synchronized static void addModificationRequest(FieldUpdater fieldUpdater)
    {
        requestQueue.add(fieldUpdater);
    }
}

:

    Main.addModificationRequest(new FieldUpdater()
    {
        public void run()
        {
            Main.b.name = "NewNameB";
        }

        public Field getField()
        {
            return Main.class.getField("name");
        }

    });

Note that for clarity, I deliberately skipped work with Exceptions that can be fetched from getField (). Also, this is not a good code design, but it fixes your code as indicated.

0
source

All Articles