Pomocnik kontra model? Z którego powinienem korzystać?

9

Pracuję z API Instagram w Magento. Daję kupony moim obserwatorom na Instagramie, jeśli obserwują nasz sklep na Instagramie.

Wywołuję API do instagram w PHP za pomocą curl. Obecnie zawijam wywołania API w funkcjach pomocniczych w moim niestandardowym module. Czy zamiast tego powinienem zawijać te wywołania w funkcji wewnątrz modelu?

Na przykład. Wykonuję wywołanie API na Instagramie, aby ustalić, czy bieżący użytkownik obserwuje moje konto. Tak więc w moim kontrolerze wywołuję funkcję pomocnika, która zwraca kontrolerowi status śledzenia. W moim kontrolerze w razie potrzeby zaktualizuję swoje modele.

Czy mam rację, umieszczając te wywołania API w funkcjach pomocniczych? Kiedy używam pomocników w przeciwieństwie do modeli?

<?php

class Company_SocialCoupons_InstagramController extends Mage_Core_Controller_Front_Action
{
    public function followAction() {

       $status = Mage::helper('socialcoupons/instagram')->getFollow();

       if ($status == 'follows') {

            // 1. ADD DATA TO MY DATABASE using my custom model
            //    - Ex. Mage::getModel('socialcoupons/instagram')->setInstagramId(*IGID*), etc. 
            // 2. CREATE COUPON
            // 3. EMAIL COUPON TO CUSTOMER
       }
}

class Company_SocialCoupons_Helper_Instagram extends Mage_Core_Helper_Abstract
{

public function getfollow() {

    $accessToken = $this->getAccessToken();
    $relationshipsUrl = 'https://api.instagram.com/v1/users/' . $this->getUserId() . '/relationship?access_token=' . $accessToken;

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $relationshipsUrl);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json'));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $jsonData = curl_exec($ch);
    curl_close($ch);

    $response = json_decode($jsonData, true);
    $status = $response['data']['outgoing_status'];
    return $status;
}

public function generateAccessToken($code) {

    // exchange code for access token
    $accessTokenUrl = 'https://api.instagram.com/oauth/access_token';
    $data = array(
        'client_id'     => $this->getClientId(),
        'client_secret' => $this->getClientSecret(),
        'code'          => $code,
        'grant_type'    => 'authorization_code',
        'redirect_uri'  => $this->getRedirectUri()
    );       

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $accessTokenUrl);
    curl_setopt($ch, CURLOPT_POST, count($data));
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json'));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $jsonData = curl_exec($ch);
    curl_close($ch);

    $response = json_decode($jsonData, true);

    if (isset($response['error_type'])) { // no error

        Mage::getSingleton('core/session')->unsInstagramAccessToken();
        Mage::getSingleton('core/session')->addError($response['error_message']);
        return $this->_redirect('*/*/authorize');  
    } 

    $accessToken = $response['access_token'];
    $id          = $response['user']['id'];
    $username    = $response['user']['username'];

    Mage::getSingleton('core/session')->setInstagramAccessToken($accessToken);      

    return array(
        'id'       => $id,
        'username' => $username
    );
}

}

Alex Lacayo
źródło

Odpowiedzi:

18

Najpierw musisz zadać sobie pytanie, jaka jest różnica między modelem a pomocnikiem. Najczęstszą odpowiedzią jest „model ma za sobą tabelę”. Następnie zadaj sobie pytanie „dlaczego obserwatorzy są wymienieni jako modele, a nie pomocnicy”.

Pomocnicy nie powinni istnieć. Ale najczęstszą praktyką jest ... kiedy nie wiesz, gdzie umieścić jakiś kod, umieszczasz go w pomocniku.
To jest złe, moim zdaniem. Korzystanie z pomocników nie jest tak naprawdę w duchu OOP. Po prostu grupujesz niektóre niezależne funkcje wewnątrz klasy.

Ale dość filozoficznej rozmowy.
Użyłbym modelu. Głównie dlatego, że pomocnicy są zawsze singletonami. Mage::helper()zawsze zwraca to samo wystąpienie klasy pomocniczej.
W przypadku modeli można uzyskać nowe wystąpienia i singletony, w zależności od potrzeb. Jest więc nieco bardziej elastyczny przy użyciu modelu.

Ale w tym konkretnym przypadku, jeśli potrzebujesz tylko jednego wystąpienia klasy, możesz użyć pomocnika lub modelu. Nie ma różnicy. Właśnie to sprawia, że ​​czujesz się komfortowo.

Marius
źródło
Dzięki za to. Kiedy tworzę nową klasę modelu, która po prostu wykonuje wywołania APi, czy muszę rozszerzyć Mage_Core_Model_Abstract, czy nie muszę niczego przedłużać?
Alex Lacayo,
3
Nie musisz rozszerzać modelu abstrakcyjnego. Ale możesz rozszerzyć Varien_Object. Może to być przydatne, ale nie obowiązkowe
Marius
2

Twierdziłbym, że jest bardziej odpowiedni dla modelu, ponieważ jego głównym celem jest dostęp do danych i reprezentowanie ich.

Moduły handlowe
źródło
2

Model:

echo $MyModel->getUserName();

Pomocnik:

echo $MyHelper->getFullname($SomeModelThatImplementsSomeStuff)..

Jeśli ma STAN WEWNĘTRZNY, jest to model. Jeśli nie, jest to pomocnik ze wszystkimi poprawnymi funkcjami matematycznymi, takimi jak sin(x)lub str_tolower($text). Model ma stan wewnętrzny, a pomocnik otrzymuje stan wstrzykiwany jako zależność.

Roger Keulen
źródło
1

Jeśli metody są używane przez wiele klas (bloki / modele / kontrolery) i wspólne dla wielu modeli, pomocnik jest oczywistym wyborem.

Jeśli metody są kiedykolwiek używane tylko podczas tworzenia pojedynczego modelu, wówczas w tym modelu jest właściwe miejsce.

choco-loo
źródło