Mi sono confuso se è necessario un dominio per accedere a un servizio esterno in alcuni stati del suo ciclo di vita.
La regola aziendale è questa:
If an Employee is accepting a JobSeeker's JobApplication, then the Employee must create an Appointment and have it e-mailed to the JobSeeker.
Le mie soluzioni attuali sono:
1 - Lascia la responsabilità di invio al dominio JobApplication
class JobApplication {
public function makeAppointment(IMailService $mailService, IMailGenerator $mailGen, \DateTime $time, Address $address = null) {
$employer = $this->getVacancy()->getEmployer();
$this->accept();
$appointment = new Appointment($employer,
$this->applicant,
'Interview Invitation - '.$employer,
$time,
$address ?: $employer->getAddress()
);
$mailService->send(
$appointment->getJobSeeker()->getMail(),
$appointment->getTitle(),
$mailGen->generateAppointmentMail($appointment)
);
return $appointment;
}
}
Mi sento in imbarazzo con questa opzione, poiché lascia l'entità JobApplication a dipendere dai servizi di Mailing.
2 - Crea un nuovo AppointmentService
class AppointmentService {
private $mailService;
private $mailGen;
public function __construct(IMailService $mailService, IMailGenerator $mailGen) {
$this->mailService = $mailService;
$this->mailGen = $mailGen;
}
public function makeAppointmentFromJobApplication(JobApplication $application, \DateTime $time, Address $address = null) {
$jobApplication->accept();
$appointment = new Appointment($application->getCompany(),
$application->getApplicant(),
'Interview Invitation - '.$application->getCompany(),
$time,
$address ?: $application->getCompany()->getAddress()
);
$mailService->send(
$appointment->getJobSeeker()->getMail(),
$appointment->getTitle(),
$mailGen->generateAppointmentMail($appointment)
);
return $appointment;
}
}
Questa opzione è utile poiché ho solo bisogno di iniettare AppointmentService sul controller, ma lascia la classe Appointment anemica.
Una volta ho letto per non lasciare mai il dominio dipendente dai servizi di dominio, l'altro modo è corretto. Tuttavia, alcune regole aziendali richiedono servizi esistenti nell'ambito del dominio.
Ci sono altre opzioni?
Aggiornamento - 1
Una terza opzione sarebbe come questa:
class Employer {
public function acceptApplication(JobApplication $application) {
if($application->isRejected()) throw new \Exception('Cannot make appointment for rejected application');
$application->setAccepted();
}
public function makeAppointment(IAppointmentService $appointmentService, JobApplication $application, \DateTime $time, Address $address = null) {
if(!$application->isAccepted()) $this->acceptApplication($application);
return $appointmentService->makeAppointment($this, $application->getApplicant(), $time, $address ?: $this->getAddress());
}
}
class AppointmentService {
private $mailService;
private $mailGenerator;
public function makeAppointment(Employer $company, JobSeeker $jobSeeker, \DateTime $time, Address $address = null) {
$appointment = new Appointment($company,
$jobSeeker,
'Interview Invitation - '.$application->getCompany(),
$time,
$address
);
$this->mailAppointment($appointment);
return $appointment;
}
private function mailAppointment(Appointment $appointment) {
return $mailService->send($appointment->getJobSeeker, $appointment->getTitle, $mailGenerator->generateApplicationAppointment());
}
}