2017-03-10 2 views
0

Ich schreibe eine einfache Symfony2 Web-Anwendung. Ich erkannte, dass fast jeder Controller in meiner Anwendung die gleichen Operationen ausführt, aber auf einem anderen Objekt. Ich spreche über Standard-CRUD-Operationen: Erstellen, Lesen, Aktualisieren und Löschen. Ich werde 'Entfernen' als BeispielSymfony 2 - Möglichkeiten, redundanten Code zu reduzieren

Beispiel verwenden:

class CustomerController { 
/** 
* @Route("/customer") 
* @Method("DELETE") 
*/ 
public function deleteAction(Request $request){ 
    $rep =this->getDoctrine()->getManager()->getRepository('AppBundle:Customer'); 

    $customerId = $request->get('id'); 
    if ($customerId != null) { 
     $rep->delete($customerId); 
    } else { 
     $rep->deleteAll(); 
    } 
    $response = new Response(null, Response::HTTP_OK); 
    return $response; 
} 
} 

class ProductController { 
/** 
* @Route("/product") 
* @Method("DELETE") 
*/ 
public function deleteAction(Request $request){ 
    $rep =this->getDoctrine()->getManager()->getRepository('AppBundle:Product'); 

    $productId = $request->get('id'); 
    if ($productId != null) { 
     $rep->delete($productId); 
    } else { 
     $rep->deleteAll(); 
    } 
    $response = new Response(null, Response::HTTP_OK); 
    return $response; 
} 
} 

class CompanyController { 
/** 
* @Route("/company") 
* @Method("DELETE") 
*/ 
public function deleteAction(Request $request){ 
    $rep =this->getDoctrine()->getManager()->getRepository('AppBundle:Company'); 

    $companyId = $request->get('id'); 
    if ($companyId != null) { 
     $rep->delete($companyId); 
    } else { 
     $rep->deleteAll(); 
    } 
    $response = new Response(null, Response::HTTP_OK); 
    return $response; 
} 
} 

und so weiter ...

Das einzige, was wirklich ändert, ist die Entity-Name ("Kunde", „Produkt "," Firma ", etc ...).

Haben Sie Ideen, wie Sie diese Redundanz beseitigen und gleichzeitig den Code lesbar halten können?

Das erste, was mir in den Sinn kommt, ist eine Basisklasse mit der Logik der Löschmethode zu erstellen und den Entitätsnamen als Parameter zu übergeben. Ist es in Ordnung, dies zu tun? Zum Beispiel:

class CustomerController extends BaseController{ 
/** 
* @Route("/customer") 
* @Method("DELETE") 
*/ 
public function deleteAction(Request $request){ 
    parent::deleteAction($request, 'AppBundle:Customer'); 
} 

Ist die obige legit Lösung? Gibt es Möglichkeiten, es weiter zu vereinfachen?

Antwort

1

Ich würde einen einzigen Controller verwenden. Verwenden Sie die Route, um den Entitätsklassennamen abzurufen.

/** 
* @Route("/{entityName}/{entityId}") 
* @Route("/{entityName}") 
* @Method("DELETE") 
*/ 
public function deleteAction($entityName, $entityId = null){ 
    $rep =this->getDoctrine()->getManager()->getRepository('AppBundle:'.$entityName); 
    if ($productId != null) { 
     $rep->delete($productId); 
    } else { 
     $rep->deleteAll(); 
    } 
    $response = new Response(null, Response::HTTP_OK); 
    return $response; 
} 
} 

Je nachdem, wie Sie Ihre Routen bauen sollten Sie den $ entityName String zum Beispiel übersetzen müssen:/Entity-Namen EntityName oder/Einheit Entity

+0

Der paranoide Programmierer wäre besorgt über einen Benutzer bekommen Erlaubnis, das auszuführen, und dann in der Lage sein, jeden Datensatz in der Datenbank durch ID –

+1

zu löschen Das ist ein anderes Problem aus meiner Sicht. Natürlich müssen diese Punkte irgendwie abgesichert werden. In einem ersten Schritt könnten Sie eine weiße Liste erlaubter Entitäten erstellen, die gelöscht werden. – Carlos

+0

Ich habe gemischte Gefühle gegenüber diesem Ansatz. Auf der einen Seite reduziert es die Menge an redundantem Code erheblich. Auf der anderen Seite denke ich, dass es das Prinzip der "einheitlichen Verantwortung" verletzen könnte. Es macht auch Code ein bisschen schwerer zu lesen. Wie auch immer, danke für diese Idee. Noch eine Frage: Wie würdest du einen solchen Controller benennen? –