I have a strange question about OOP and interfaces that messed up my mind trying to find a better design.
There are two different classes that do the same job (for example, sending a message) in different environments. These two environments use different parameters to determine the recipient; one uses a mailing address and the other uses a username. Thus, both classes have the same, but slightly different ways of sending a message.
MessageSenderViaMailManager.cs
public bool SendMessage(string recipientMailAddress, string message) { .. }
MessageSenderViaUsernameManager.cs
public bool SendMessage(string recipientUserName, string message) { .. }
In both classes, there are other similar methods that are responsible for the same work, but may require different parameters. To use these managers with an interface, I created a name that is IMessageSenderManager and contains a definition similar to this.
public bool SendMessage(string recipientUserName, string recipientMailAddress, string message);
So, both SendMessage methods in my classes have been changed to:
public bool SendMessage(string recipientUserName,string recipientMailAddress, string message) { .. }
With this new SendMessage method, I can use the appropriate parameter to use as the recipient (email address or username). This seems to be fine, but the implementation looks weird. Because I have to send all the parameters, not knowing what will be used at runtime during encoding. For instance:
Like the code above, sending a message to a mailing address looks similar.
In my opinion, this is not a very good design, so I started thinking about the best solution. Bacause, if I want to implement another MessageSender provider that uses a different descriptor for the receiver, I need to add another parameter to my interface, so for all classes. I thought I could change two recipient parameters with one common recipient parameter and send the appropriate value for the context. But I'm trying to use this in a dynamic environment, and the way (via username or mail) will be determined at runtime, so I could not use this.
I plan to do this, a flexible library that can be used untied or unit test friendly for other developers, and I do not want to confuse them with meaningless parameters or poor design.
Is there a better design for this situation?
EDIT:
Actually, by my mistake, I forgot a very large and important part of my question, I regret it. As you can see from the answers, there are several alternatives to solve my first problem described above. But after? I mentioned in the code, the interface is returned from the MessageSenderFactory () method, but I do not know which message sender manager has returned. Therefore, I have two options:
- Write a condition to check which manager returns from the method, and send the required parameters for this manager with the correct values and send to others empty.
- Send all parameters with the corresponding values regardless of the manager, so both of them can work without problems. But in the future, if another manager is added, than I will need to send additional parameters for this manager, every time.
- Is there any other way that I could not think of yet?
Also, methods other than SendMessage may require different parameters according to the manager, which is unknown at runtime. For instance:
MessageSenderViaMailManager The AddContact method may require the following parameters:
- Contact name
- Contact mail
- contact number
- Contact MailType (rich, plain)
or MessageSenderViaUserNameManager AddContact may need to complete the following parameters:
- Contact name
- Contact mail
- Username contact
- Contact Message Platform (Twitter, facebook, vs)
- Contact sender name
Thus, this makes everything very complex. How should my IMessageSenderManger AddMethod be? Should they contain all parameters? Should I overload it? Or should I put the general parameters in the method and make other parameters that are changed by the anonymous manager (for example, HtmlHelper in MVC)
I know this question is not very strong, and I am not good at English.
GitHub EDIT:
I created a small example and uploaded to github, hope this helps me better explain my question https://github.com/bahadirarslan/InterfaceDesign