Kevin-Mitnick Şöyle bir şey olabilir belki, hızlıca yazıyorum:
interface ReportInterface
{
public function generate(Carbon $startsAt, Carbon $endsAt);
}
interface ChartableReportInterface
{
public function toChart(Carbon $startsAt, Carbon $endsAt): JsonResponse;
}
interface ReportFactoryInterface
{
public function build(ReportInterface $report, $period): ReportFactory;
public function report();
public function toChart();
}
abstract class ReportPeriod
{
public const DAILY = 'daily';
public const WEEKLY = 'weekly';
//...
}
class ReportFactory implements ReportFactoryInterface
{
public function build(ReportInterface $report, $period): ReportFactory
{
[$startsAt, $endsAt] = $this->resolveDatesFromPeriod($period);
$this->startsAt = $startsAt;
$this->endsAt = $endsAt;
$this->report = $report;
return $his;
}
public function report()
{
return $this->report->generate($this->startsAt, $this->endsAt);
}
public function toChart()
{
return $this->report->toChart($this->startsAt, $this->endsAt);
}
public function resolveDatesFromPeriod($period)
{
if(is_array($period)) {
return $period;
}
switch($period) {
case ReportPeriod::DAILY:
return [
now()->startOfDay(),
now()->endOfDay()
];
break;
case ReportPeriod::WEEKLY:
return [
now()->startOfWeek(),
now()->endOfWeek()
];
break;
}
}
}
Şimdi kullanmaya geldi. Örneğin ürünlerin siparişleri ile ilgili bir rapor oluşturacaksınız diyelim:
class ProductOrderReport implements ReportInterface, ChartableReportInterface
{
public function generate(Carbon $startsAt, Carbon $endsAt)
{
// Buraya $startsAt ve $endsAt kullanarak bir sorgu yazacaksınız.
// Elbette nasıl döneceğini siz belirleyeceksiniz.
// ...
}
public function toChart(Carbon $startsAt, Carbon $endsAt): JsonResponse
{
// Buraya $startsAt ve $endsAt kullanarak bir sorgu yazacaksınız.
// Elbette nasıl döneceğini siz belirleyeceksiniz.
// Chart datası olduğu için JSON dönecektir.
// ...
}
}
Daha sonra bunu controller içerisinde şöyle kullanabilirsiniz:
public $reportFactory;
public function __construct(ReportFactoryInterface $reportFactory)
{
$this->reportFactory = $reportFactory;
}
public function index(Request $request)
{
$period = $request->input('period'); // daily, weekly gibi...
$report = $this->reportFactory->build(new ProductOrderReport, $period);
return $report->generate();
// ya da
// return $report->toChart();
}
Bu şekilde uygulamanızı servislere bölerek daha esnek bir mimari oluşturabilir ve IoC ilkesine göre frameworkün etinden sütünden her şeyinden yararlanırsınız, işin ameleliğini framework yapar. Artık bu raporu her yerde kullanabilirsiniz.
Basit ya da tek seferlik bir şey ise if...else... ya da switch yazın gitsin, size kalmış.