I have a class named Change which should be abstract and have some basic methods. I have classes Insert, Update and Delete that extends Change. In the case of Insert, Update I just use extend and add no logic!

public class Insert extends Change {}

In the Delete class I have an extra method that doesn't exist in the Change class (which is the base abstract class).

It seems to be wrong design, that I have classes like Insert and Update that extend from Change but don't do anything (no logic in this classes) . What do you think? what should be the hierarchy?

EDIT: There is an endpoint in the service that returns an object named ChangedEntities and the consumer of this endpoint which is another service use this endpoint to insert/update/delete entities in the DB. So the consumer of this endpoint gets,

public class ChangedEntities {
    private Insert inserations;
    private Update updates;
    private Delete deletions;
}

public class Change {
    private List<Entity> entities = new ArrayList();

    public void addEntity(Entity entity) {
        entities.add(entity);
        // the logic is more complex and is common to insert/update/delete
    }
}

public class Insert extends Change {}

public class Delete extends Change {

    public void logDeletion() {
        System.out.println("Deleted successfully");
        // this should be some complex method
    }
}
  • Is the purpose of the class Change (and its child classes Insert, Update, Delete) only to keep track of changes? Or, do they have other executable content? In other words, are Change classes commands, or just "receipts" ? – Nick Alexeev Nov 21 at 0:18
  • Those classes contain the list of changes and in the end I need to send to other service an object like this: inserations: [] , updates: [], deletions: [] – T.S Nov 21 at 6:50
  • Is Delete supposed to be able to support addEntity? This seems wrong if it is. As it stands, it's hard to see the purpose of Change itself, or why functionality for Insert is in that class, rather than Insert. – David Arno Nov 21 at 11:37
up vote 3 down vote accepted

I wouldn’t make any of these subclasses.

I’d create an interface Loggable which Change would implement, and let clients of the class decide whether they want to log or to separate their Change instances with different variable names.

They carry the exact same behaviour, so I don’t see any reason to create other classes.

Also if you think Delete should be a class because log will be complex, then the problem may be that it is too complex. Conceptually, you’re logging a change that happened. Make a simple tool and let users of the class use it with their own degree of complexity.

To me, it's perfectly ok to have a class like Insert just extend Change without adding anything to the parent.

It seems quite natural to me to have three different classes Insert, Update and Delete. They are a part of you domain language, I suppose. And probably it's useful if they all are subclasses or implementations of a common abstract class or interface named Change.

It's up to you as the developer to decide how to implement them, and I see three different ways (with a strong preference on the second one):

  • Repeat the method implementations in every subclass: NO, DON'T REPEAT YOURSELF!

  • Have the classes inherit the implementations from an abstract parent like Change: I'd do it that way, and if some subclass can inherit everything it needs, the better!

  • Advocates of "Composition over Inheritance" might introduce a class like CommonChangeOperations, give each of the three classes a delegate field of this type, and have all methods delegate to these instances. To me, that seems like overkill engineering.

So, to me the hierarchy

  • Change
    • Insert
    • Update
    • Delete

is perfectly ok, with Change carrying all the common aspects of the implementation.

  • The only thing that makes me think twice before going with the second approach is that extends should add some functionality as far as I know. the third approach seems to be to much delegation – T.S Nov 22 at 6:02

Personally, I think the design is wrong.

Conceptually, classes represent objects, not verbs or actions. It seems to me that you are trying to do functional programming using OOP resources. Ask yourself, did you ever found an object "change" in reality?

I don't know what is your goal, but "change" is an action you perform to something. For example, your database. But actions would be concrete. I never recall implementing a "change()" method.

Take the java.util.list as an example of what should be done. It provides the methods add(), remove(), set(), etc., which can be overridden. A List is something that you can "change".

So, you can create your objects, and abstractions, if needed, as for example

public class MyDatabase {...

and provide methods as...

public void add(SparePart part) {

in order to have clear and legible procedures:

Wheel w=getLastWheelModel();
db=new MyDatabase(params...);
db.add(w);

(where Wheel extends SparePart, and where you can add your abstractions).

  • If I understood correctly, you say to create a class named Entities and add insert, update, delete methods, but I need to keep a list of the entities that need to inserted, updated, deleted. should I do this in the Entities class? is this what you meant? – T.S Nov 22 at 5:59
  • Yes, if Entities is the bag/database/repository/whatever where you perform the actions, yes. "Entities" as a name is quite generic, so I don't know if you are talking of tables, solids, spare parts, ideas, registers, indexes, etc. – RodolfoAP Nov 22 at 7:55

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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