I'm sorry if the phrasing of the question is a bit unclear but let me try to clarify below. (If anyone can word it better, feel free to edit)
I have a Map instance variable, groups, which is defined as follows with the given type parameters:
Map<Group, Map<Username, GroupMember>> groups
Within the same enclosing class, I have a public method, addGroup(Group group), which is supposed to put a new entry into the groups map. The Group object contains all the relevant information for the entry.
The conundrum here stems from the fact that adding a new element to groups would require that I specify a concrete object for Map<Username, GroupMember> value within addGroup(), thus internally coupling the abstraction with an implementation--clearly in violation of the dependency inversion principle.
My question is then how do I avert this problem? I hesitate delegating the responsibility of defining the object to the caller (i.e. defining the method as addGroup(Group group, Map<Username, GroupMember> groupMembers) for instance) as it chips away at abstraction, may be inconsistent with the constructor injected implementation; and in my opinion, introduces unnecessary coupling with the class implementation details. Perhaps I should reconsider my design. Would appreciate your feedback.
EDIT
Here's where the problem is coming from:
public class Foo {
private final Map<Group, Map<Username, GroupMember>> groups;
//...
public void addGroup(Group group) {
if (exists(group))
throw new IllegalOperationException("Group with same name already exists");
//Declaring a new HashMap within the class (i.e. defining the implementation within a class member)
groups.put(group, new HashMap<Username, GroupMember>(Map evaluation based on group object)));
}
//...
}
Here's what I'm hesitant of doing:
//Passing Map<Username, GroupMember> object decreases abstraction and exposes implementation details
public void addGroup(Group group, Map<Username, GroupMember> groupMembers) {
if (exists(group))
throw new IllegalOperationException("Group with same name already exists");
groups.put(group, groupMembers));
}
Here's part of the definition for Group to further add context;
public class Group {
private final String name;
private final String description;
private final Instant dateCreated;
private final Collection<GroupMember> members;
//... Constructor and getters for the fields
}