Does visitor pattern lead to violation of SRP?
Penso che siano generalmente concetti ortogonali. Ma è sicuramente una violazione del concetto forse più importante - incapsulamento .
La prima riga in wikipedia dice:
the visitor design pattern is a way of separating an algorithm from an object structure on which it operates.
E questo è un tratto vivido della programmazione procedurale, in contraddizione con i principi di base dell'OOP. Quindi, secondo me, la logica di calcolo dell'equilibrio dovrebbe risiedere nella classe 401k. Tuttavia, ciò non significa che non puoi usare altre classi per aiutarti. Puoi, ma senza esporre il comportamento interno di 401k
.
Ma c'è un problema di 401k
che diventa un oggetto di Dio, menzionato da Doc Brown. Vorrei dare un'occhiata se avete bisogno di un oggetto 401k che rappresenta la stessa classe in tutti quei casi d'uso in cui vengono chiamati i suoi metodi attuali. Prima di tutto, considera i tuoi contesti limitati. Dubito che la stessa classe debba rappresentare un caso d'uso per aggiungere un contributo e generare un rapporto (inoltre, dubito che abbiate mai bisogno di un oggetto quando tutto ciò di cui avete bisogno è la rappresentazione dei dati). Le probabilità sono che appartengono a diversi BC. Di conseguenza, puoi dividere il modello sul lato di scrittura e lettura. Aggiungere un contributo è un modello di scrittura, il tuo dominio, mentre un calcolo del saldo probabilmente potrebbe essere il tuo read model .
Ecco come potrebbe essere il repository del rapporto:
class C401kReportRepository
{
public function report()
{
// query your database
return
[
[
'year' => 2017,
'month' => 11,
'amount' => 10000,
]
];
}
}
La tua ContributionsList
può essere esposta solo se stai utilizzando un ORM ( che non è obbligatorio , a proposito), e questo può essere fatto implicitamente dal framework stesso, usando la riflessione, per esempio. Il punto non è esporlo a clienti arbitrari. Quindi se i dati di ContributionsList
vengono utilizzati all'interno di un certo insieme di oggetti ( 401k
oggetto nel tuo caso), non è un grosso problema. Dopo tutto, i tuoi dati devono essere esposti da qualche parte. Basta non renderlo un'esposizione di default, con i getter.