Reputation: 329
I have a Java question and I can't see how I can implement the methods correctly. I am not very good with architecture.
Data Manager interface class:
public interface DataManager {
public void readData();
public void writeData();
}
Data abstract class:
public abstract class Data implements DataManager {
@Override
public void readData() {};
@Override
public void writeData() {};
}
Data Reader class:
public class DataReader extends Data {
// I want to implement the readData() here
}
Data Writer class:
public class DataWriter extends Data {
// I want to implement the writeData() here
}
If I want to implement the readData() and writeData() separately in two different classes with only one interface, is it possible? I don't know why I am doing this way. Maybe it just looks cleaner and easier when I add more methods to the reader or writer class. Should I implement everything in just one single class?
I want this library to allow users using the manager object to have access for data reading and writing. But for implementation, I don't know how I can do it correctly.
Upvotes: 1
Views: 3034
Reputation: 329
After a lot of modification, so I do it this way and I think it fits my solution.
Data Manager interface class:
public interface DataManager {
public Data readData(); // from database
public void writeData(); // to database
}
DataConnector class:
public class DataConnector implements DataManager {
DataCreate creator = new DataCreate();
@Override
public Data readData() {
return creator.readData();
};
@Override
public void writeData() {
creator.writeData();
};
public Connection getConnection() {...};
public void close() {...};
}
Data Create class:
public class DataCreate {
public void readData() {
new DataReader().readData();
}
public void writeData() {
new DataWriter().writeData();
}
}
Data Reader class:
public class DataReader {
// I want to implement the readData() here
public Data readData(){...};
}
Data Writer class:
public class DataWriter {
// I want to implement the writeData() here
public void writeData(){...};
}
Example:
DataManager manager = new DataConnector();
manager.readData();
manager.writeData();
So clients will only use methods from the manager public interfaces to do database reading and writing. Edward Peters mentioned composition to me and I did not understand it at that time. I am not very sure if what I am doing now is what composition should be doing. I think the credit should go to him. Thanks for the help.
Upvotes: 0
Reputation: 1146
Looks like you've stumbled on the reason for the "Interface Segregation Principal". https://en.wikipedia.org/wiki/Interface_segregation_principle
While DataReader
and DataWriter
may seem related at first, and it might look like it makes sense to group them into your common interface DataManager
, the job of reading and writing is quite different, and warrants a separation into two interfaces, e.g. IReader
and IWriter
.
Suppose you have a class that needs both a reader and a writer together, and so your DataManager
interface makes sense. However, there's nothing stopping you from passing two objects, one of type IReader
and one of type IWriter
even if they're the same class underneath. But it seems you've already separated them into DataReader
and DataWriter
, which is good. As one of the other answers suggests, this is the application of the Single Responsibility Principal.
Upvotes: 3
Reputation: 417
If you're only having a certain subclass implement each method, you don't need DataManager
or Data
. Just have DataReader
and DataWriter
contain only the methods they need, like so:
public class DataReader {
public void readData() {...}
}
...
public class DataWriter {
public void writeData() {...}
}
The whole reason of extending and implementing is to either clean up code, or allow for overriding another method. The way you're doing it does neither, so why not just keep it simple?
Upvotes: 0
Reputation: 3433
A best practice in programming is the "Single Responsibility Principle". A reader is not a writer, so it shouldn't be a subtype of a DataManager
that requires its implementors to be both. By defining an abstract class that creates empty methods for the entire interface, you've also lost the value of having an interface. An interface is a contract that every implementor must /be-a/ case of its supertype. A reader is not a candidate to /be-a/ reader and a writer. You want a separate reader and writer interface, and have your readers implement one, writers the other, and datamanagers can implement both.
Also, don't use Reader
and Writer
in names for types that aren't subtypes of java.io.Reader
and java.io.Writer
, respectively. Since you're thinking of "data managers", maybe you could use ReadManager
and WriteManager
, or something like that, that lets people know you aren't using the standard Reader
and Writer
hierarchies.
Upvotes: 2