Should Domain objects for a public API be able to save/send themselves?
This is a clear setup:


FilingCabinet cabinet = room.getFilingCabinet();
File file = cabinet.get("my-unique-id");
file.setName("my-new-name");
cabinet.store(file);



You can get files from the cabinet, modify the file,
and put the file back into the cabinet for storage.
The cabinet is in charge of storing the file.

This is an unclear, confusing setup:


FileWithSave file = company.getSecretary().getFile("my-unique-id");
file.setName("my-new-name");
file.store();



There is a company.
The company has a secretary.
You can get files from the secretary, modify the file,
and the file can store itself.

The second setup makes me wonder about several things:


Who's in charge of storing the file?
After I do .store(), does the secretary still have the same vision of the file as me?
What if I want to store the file somewhere else? For example, at a different company, or in a cabinet.


In the first setup I don't need to ask such questions,
as the answers are obvious.

Single responsibility principle

Another warning sign is that the second setup violates the single responsibility principle. The FileWithSave is not just a file anymore, it's also in charge of storage.
You might say, that's kind of the point, hence the name file-with-save.
Inheritance is not really about giving additional responsibilities to classes.
The purpose of inheritance is more about specialization.
The best sub-classes do the same things as their parents, just differently.
Giving a file the additional responsibility to save itself seems too much.
Even if this is not inherently a bad design,
you can replace with a better one (the first one), and so you should.

Bad practices

Use interface types instead of implementations.
This is especially crucial in interface definitions.
So instead of this:


public interface PrivateFilingCabinet {
    FileWithSaveImpl get(String id);
    void store(FileWithSaveImpl file);
}



It should have been:

public interface PrivateFilingCabinet {
    FileWithSave get(String id);
    void store(FileWithSave file);
}