Ho studiato i modelli di progettazione creativa per la scorsa settimana, perché ho un caso d'uso comune che continua a venire, e non riesco a capire quale modello si adatta al disegno di legge.
Ecco uno scenario semplificato: ho diversi tipi di notifiche, ad es. e-mail, SMS (messaggio di testo), ecc. - e non voglio che il client sappia quale tipo creare o come crearlo, cioè il client non sa nulla delle implementazioni di INotification
.
Di seguito è il mio tentativo di approccio "metodo di fabbrica".
internal interface INotification
{
void Send();
}
public sealed class EmailNotification : INotification
{
private EmailAddress _sourceAddress;
private EmailAddress _destAddress;
public struct EmailAddress
{
public string LocalPart { get; set; }
public string DomainPart { get; set; }
public EmailAddress(string localPart, string domainPart) : this()
{
LocalPart = localPart;
DomainPart = domainPart;
}
}
internal EmailNotification(EmailAddress sourceAddress, EmailAddress destAddress)
{
_sourceAddress = sourceAddress;
_destAddress = destAddress;
}
void INotification.Send()
{
// send via email technology
throw new NotImplementedException();
}
}
public sealed class SmsNotification : INotification
{
private PhoneNumber _sourceNumber;
private PhoneNumber _destNumber;
public struct PhoneNumber
{
public ushort CountryCode { get; set; }
public ushort AreaCode { get; set; }
public ushort ExchangeCode { get; set; }
public ushort LineNumber { get; set; }
public PhoneNumber(ushort countryCode,
ushort areaCode,
ushort exchangeCode,
ushort lineNumber) : this()
{
CountryCode = countryCode;
AreaCode = areaCode;
exchangeCode = ExchangeCode;
LineNumber = lineNumber;
}
}
internal SmsNotification(PhoneNumber sourceNumber, PhoneNumber destNumber)
{
_sourceNumber = sourceNumber;
_destNumber = destNumber;
}
void INotification.Send()
{
// send via SMS tecnology
throw new NotImplementedException();
}
}
internal class NotificationFactory
{
internal INotification CreateSmsNotification(
SmsNotification.PhoneNumber sourceNumber,
SmsNotification.PhoneNumber destNumber)
{
return new SmsNotification(sourceNumber, destNumber);
}
internal INotification CreateEmailNotification(
EmailNotification.EmailAddress sourceAddress,
EmailNotification.EmailAddress destAddress)
{
return new EmailNotification(sourceAddress, destAddress);
}
}
Lo userei dal client in questo modo:
var factory = new NotificationFactory();
var notification = factory.CreateEmailNotification(
new EmailNotification.EmailAddress("myname", "nothing.com"),
new EmailNotification.EmailAddress("yourname", "nothing.com"));
notification.Send();
Ora, so che un approccio al metodo factory dovrebbe coinvolgere solo un metodo che richiede, ad es., un'enumerazione per determinare il tipo dell'oggetto restituito. Non ho visto alcun riferimento che utilizza l'approccio di cui sopra in cui esistono più metodi specializzati. Sto chiamando lo schema sbagliato? Lo sto facendo nel modo sbagliato (cioè dovrei usare un modello diverso)?
Ho anche preso in considerazione l'utilizzo di un'iniezione di dipendenza con un contenitore DI, ma la mia comprensione è che il modello semplifica i test ed è un'alternativa (o riorganizzazione) dei vari modelli di progettazione di fabbrica. In definitiva, avrei lo stesso problema, credo, nel mio contenitore DI che sta cercando di capire come prendere input complessi e decidere quale sottoclasse produrre.
Forse ho bisogno di una combinazione di fabbrica e costruttore. So che un builder è usato per produrre un singolo tipo (in contrasto con una factory che emette un determinato tipo derivato o implementazione dell'interfaccia), ma il fatto che io abbia più metodi coinvolti per creare determinate istanze specializzate sembra più un costruttore. p>
Qualsiasi aiuto sarebbe molto apprezzato.