Langsung ke konten utama

Service Tagging di Symfony

 Ketika kita bekerja dengan Service di Symfony, aplikasi kita akan mempunyai banyak Service / Object yang saling berkaitan. Kadang kita ingin mengelompokkan beberapa Service dengan behaviour / kegunaan tertentu menjadi satu kelompok. Untuk mengelompokkan Service, kita bisa menggunakan Tags. Ada banyak tags bawaan dari symfony yang bisa anda baca langsung di https://symfony.com/doc/current/reference/dic_tags.html

Membuat Tags

Anggap saya akan membuat perbandingan jarak antar titik. Saya akan menggunakan 2 metode yang berbeda, yaitu menggunakan rumus haversine (lihat di sini) dan satu lagi menggunakan crawling ke google map. Untuk itu saya membuat 2 buah Class yang masing-masing digunakan untuk membuat formula perhitungan jarak yang akan implements ke Interface DistanceCalculatorInterface seperti potongan kode berikut:
<?php // src/DistanceCalculator/DistanceCalculatorInterface.php

namespace App\DistanceCalculator;

/**
 *
 * @author programmer
 */
interface DistanceCalculatorInterface 
{
    public function getDistance(string $latLongA, string $latLongB):float;
}
kemudian berikut potongan kode untuk masing-masing Class perhitungan
<?php // src/DistanceCalculator/HaversineCalculator.php

namespace App\DistanceCalculator;

/**
 * Description of HaversineCalculator
 *
 * @author programmer
 */
class HaversineCalculator implements DistanceCalculatorInterface 
{
    /**
     * 
     * @var float
     */
    private $pi;
    
    /**
     * 
     * @var float
     */
    const EARTH_RADIUS = 6371;
    
    public function __construct() 
    {
        $this->pi = pi();
    }
    
    public function getDistance(string $latLongA, string $latLongB): float 
    {
        $latLongA = $this->split($latLongA);
        $latLongB = $this->split($latLongB);
        
        $radianLatA = $this->getRadians(
            $latLongA[0]
        );
        $radianLatB = $this->getRadians(
            $latLongB[0]
        );
        $radianLat = $this->getRadians(
            $latLongB[0] - $latLongA[0]
        );
        $radianLong = $this->getRadians(
            $latLongB[1] - $latLongA[1]
        );
        
        $a = (sin($radianLat/2) * sin($radianLat/2)) 
                + (cos($radianLatA) * cos($radianLatB)) 
                * (sin($radianLong/2) * sin($radianLong/2));
        $c = 2 * atan2(sqrt($a), sqrt(1 - $a));
        
        return round(self::EARTH_RADIUS * $c, 2);
    }
    
    protected function split(string $latLong):array
    {
        return array_map(function (string $point) {
            return (float) $point;
        }, explode(",", $latLong));
    }
    
    protected function getRadians(float $x):float
    {
        return $x * ($this->pi / 180);
    }

}
kemudian perhitungan dari google map
<?php // src/DistanceCalculator/GMapDistanceCalculator.php


namespace App\DistanceCalculator;

/**
 * Description of GMapDistanceCalculator
 *
 * @author programmer
 */
class GMapDistanceCalculator implements DistanceCalculatorInterface 
{
    public function getDistance(string $latLongA, string $latLongB): float 
    {
        // contoh script untuk scraping ke google map
        
        return 8;
    }

}

kemudian saya buat Class DistanceCalculatorCollection yang akan dipakai untuk memuat semua Service yang implement dari  DistanceCalculatorInterface tersebut:
<?php // src/DistanceCalculator/DistanceCalculatorCollection.php

namespace App\DistanceCalculator;

/**
 * Description of DistanceCalculatorCollection
 *
 * @author programmer
 */
class DistanceCalculatorCollection 
{
    
    private iterable $calculators;
    
    public function __construct(iterable $calculators) 
    {
        $this->calculators = $calculators;
    }
    
    public function getCalculators():array
    {
        return iterator_to_array($this->calculators);
    }
}
kemudian Class Collectionnya saya panggil dari Controller:
<?php // src/Controller/DistanceController.php


namespace App\Controller;

use Symfony\Component\Routing\Annotation\Route;
use App\DistanceCalculator\DistanceCalculatorCollection;

/**
 * Description of DistanceController
 * @Route("/distance", name="distance_")
 * @author programmer
 */
class DistanceController 
{
    
    /**
     * @Route("/", name="index")
     */
    public function index(DistanceCalculatorCollection $collection)
    {
        dump($collection->getCalculators());
        exit;
    }
}
sekarang saya sudah punya 2 Class untuk menghitung dengan 2 rumus yang berbeda beserta 1 Class untuk menampung Object dari kedua Class tersebut

Mendaftarkan Service Tags

Untuk mendaftarkan kedua Class yang digunakan untuk menghitung tersebut, tambahkan di file konfigurasi services.yaml yang berada di folder config/services.yaml.  Kemudian tambahkan seperti kode berikut:
services:
    # .....
    App\DistanceCalculator\HaversineCalculator:
        tags:
            - { name: distance.calculator }
            
    App\DistanceCalculator\GMapDistanceCalculator:
        tags:
            - { name: distance.calculator }
kode di atas berarti kita mendaftarkan 2 Service dengan nama tag distance.calculator. Kemudian daftarkan juga Class Collection yang berguna untuk tempat berkumpulnya Service tersebut.
services:
    # ...
    App\DistanceCalculator\DistanceCalculatorCollection:
        arguments:
            $calculators: !tagged distance.calculator
kemudian paggil controller melalui browser maka akan muncul sepeti berikut:


kemudian jika digunakan untuk menghitung seperti potongan kode berikut:
<?php // src/Controller/DistanceController.php


namespace App\Controller;

use Symfony\Component\Routing\Annotation\Route;
use App\DistanceCalculator\DistanceCalculatorCollection;

/**
 * Description of DistanceController
 * @Route("/distance", name="distance_")
 * @author programmer
 */
class DistanceController 
{
    
    /**
     * @Route("/", name="index")
     */
    public function index(DistanceCalculatorCollection $collection)
    {
        $from = '-7.325447718127029, 112.75154637208772';
        $to = '-7.365628717636805, 112.75223597318133';
        foreach ($collection->getCalculators() as $calc) {
            $result = $calc->getDistance($from, $to);
            dump($result);
        }
        exit;
    }
}
akan keluar hasil seperti berikut:


Mendaftarkan Berdasarkan Interface

Untuk otomatis semua Class yang merupakan turunan dari interface  DistanceCalculatorInterface dengan tag distance.calculator bisa menggunakan keyword _instanceof di file services.yaml:
services:
    # ...

    _instanceof:
        App\DistanceCalculator\DistanceCalculatorInterface:
            tags:
                - { name: distance.calculator }

Komentar

Postingan populer dari blog ini

Contoh Perhitungan Algoritma Perceptron

      Melanjutkan tulisan saya sebelumnya tentang algoritma perceptron,kali ini saya akan menulis tentang conto perhitungan manual algoritma perceptron. Untuk contoh kasusnya saya menggunakan data logika AND. Cekidot.... Algoritma      Data yang kita gunakan sebagai contoh adalah data logika AND sebagai berikut: x1 x2 target 0 0 0 0 1 0 1 0 0 1 1 1       tentukan bobot awal secara acak, saya pakai contoh w1 = 0,w2 =0, learning rate = 1, bias = 0,maksimal epoh = 10. Disini saya memakai fungsi aktivasi undak biner. Epoh ke 1 Data ke satu x = {0,0}, bobot w = {0,0},b=0,target = 0 y_in = (x1*w1)+(x2*w2)+b = (0*0)+(0*0)+0 = 0 y = sign(0) = 1 karena y != target maka hitung error dan update bobot  error = target - y = 0 - 1 = -1 w1_baru = w1_lama +(learning_rate*error*x1)                = 0 + (1*(-1)*0) = 0 w2_baru = w2_lama +(learning_rate*error*x2)                = 0+(1*(-1)*0) = 0

Contoh Perhitungan Algoritma Learning Vector Quantization

Melanjutkan tulisan saya tentang algoritma Learning Vector Quantization yang lalu, kali ini saya akan melanjutkan dengan contoh perhitungan manual. Berikut ini contoh data yang akan kita hitung. No X1 X2 X3 X4 target 1 0 1 1 0 0 2 0 0 1 1 1 3 1 1 1 1 0 4 1 0 0 1 1 pada contoh di atas, saya menggunakan 4 data sebagai data training beserta target yang bertujuan untuk mendapatkan bobot yang akan digunakan pada proses klasifikasi. Bobot awal adalah { 1, 1, 1, 0} dan { 1, 0, 1, 1} dengan learning rate 0,05 dengan fungsi pembelajaran = 0,1. Pelatihan Iterasi ke 1 1. Data ke 1 { 0, 1, 1, 0} dengan target 0, bobot = {{ 1, 1, 1, 0},{ 1, 0, 1, 1}}      - menghitung bobot untuk masing masing output :          kelas 0 = sqrt(((0-1)^2)+((1-1)^2)+((1-1)^2)+((0-0)^2)) = 1         kelas 1 = sqrt(((0-1)^2)+((1-0)^2)+((1-

Pemrograman Berorientasi Object - Overloading dan Overriding

       Function atau method overloading dan override adalah fitur yang sangat mendasar dan berguna dari bahasa OOP manapun. Dalam tutorial ini kita akan membahas implementasi metode overloading dan override di php. Di sini pertama kita akan membahas dasar-dasar overloading dan override. Setelah eksplorasi dasar kita akan menerapkan overloading dan override di php. Sebelum melangkah lebih jauh, saya mengasumsikan bahwa Anda memiliki pengetahuan dasar tentang class dan pewarisan di php. Anda juga memiliki pemahaman tentang magic method di php. Magic method karena overloading di php bisa di implmentasikan dengan menggunakan magic method. Overriding        Arti dasar dari overriding di OOP sama dengan arti kata sebenarnya. Dalam arti kata sebenarnya dari overriding adalah menggantikan perilaku orang tua yang sama pada anak. Ini sama dengan override method di OOP. Dalam arti OOP, override adalah mengganti method class induk di class anak. Atau dengan method kata kunci sederhana yang me