-1

I have a problem with design a few simple classes. I want a four classes: one recursively delete directory, another copy one dir to another same way. Another two does same as first two but they add observable behaviour: calculates few parameters like estimated time or percents of doing operation and fire up observers. What is the best way of design them?

the simpliest way to do this this scheme:
schema 1

but I have problems with violation of DRY principle in code that calculates percents and other values in observable class.

I may be move that code to abstract class but i need to extends that abstract class and appropriate Copy or Delete class, this is forbidden in java

I have decision to implement strategy pattern but this uml and my code still smell.

enter image description here

what is the best solution here, where are my mistakes?

  • 1
    OOP isn't magic. There isn't one single way to do everything. Same for patterns. There's benefits and trade offs to everything. There are no silver bullets in programming. My first gut reaction is why is every action an object? – jpmc26 Feb 9 '17 at 1:13
  • 1
    I would slice the problem differently: have code responsible of iterating over the filesystem (measuring progress or whatever you need to compute) and have code reponsible of operating on individual files. You could then compose them to make operations on folders. And I say code, because those don't need to be classes. – Theraot Feb 9 '17 at 6:36
1

You have some alternatives. Each one has benefits and downsides. There's no magic formula to programming; you have to make choices based on your best guess about what will work.

Make it part of the base class

You could implement it as part of the base Action class.

public abstract class Action {
    private List<Listener> listeners;

    public Action() {
        this.listeners = new ArrayList<Listener>();
    }

    public void addListener(Listener l) {
        this.listeners.add(l);
    }

    // You'll need a remove listener function, too.

    public final void performAction() {
        for(Listener l: this.listeners) {
            l.notify(/* args here*/);
        }
        this.innerPerformAction();
    }

    protected abstract void innerPerformAction();
}

The main benefit to this is that every Action can have listeners. No one can inistantiate one that isn't capable of notifying another piece of code.

Implement a wrapper

Composition might be a good fit here.

public class ObservableAction extends Action {
    private List<Listener> listeners;
    private Action action;

    public ObservableAction(Action a) {
        this.listeners = new ArrayList<Listener>();
        this.action = a; 
    }

    public void addListener(Listener l) {
        this.listeners.add(l);
    }

    public void performAction() {
        // Do "observing" here
        this.action.performAction();
    }
}

Then,

Action deleteAction = new ObservableAction(new DeleteAction());

This one makes more sense if you need more targetted observations, in only some places. Or if you can't modify Action at all (e.g., it's in a third party library).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.