Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
528 views
in Technique[技术] by (71.8m points)

design patterns - What is a Proxy in Doctrine 2?

I just finished reading all the Doctrine 2 documentation, I started my own sandbox, I understood most of the principes, but there is still a question and I couldn't find any complete explanation in the doc.

  1. What are Proxy classes?
  2. When should I use them over entities?

As far as I understand, proxy classes add a layer to let you add some other features to your entities, but why use a proxy instead of implementing the methods themselves in the entity class?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

UPDATE

This answer contains wrong information about differences between proxy objects and partial objects. See @Kontrollfreak's answer for more details: https://stackoverflow.com/a/17787070/252591


Proxy objects are used whenever your query doesn't return all data required to create an entity. Imagine following scenario:

@Entity
class User {
     @Column protected $id;
     @Column protected $username;
     @Column protected $firstname;
     @Column protected $lastname;

     // bunch of setters/getters here
}

DQL query:

SELECT u.id, u.username FROM EntityUser u WHERE u.id = :id

As you can see this query doesn't return firstname and lastname properties, therefore you cannot create User object. Creation of incomplete entity could lead to unexpected errors.

That's why Doctrine will create UserProxy object that supports lazy loading. When you'll try to access firstname property (which is not loaded) it will first load that value from database.


I mean why should I use a proxy ?

You should always write your code as if you didn't use proxy objects at all. They can be treated as internal objects used by Doctrine.

Why the lazy loading can't be implemented in the Entitiy itself?

Technically it could be but take a look at some random proxy object's class. It's full of dirty code, ugh. It's nice to have a clean code in your entities.

Can you provide me an use case?

You're displaying a list of latest 25 articles and you want to display a details of the first one. Each of them contain a large amount of text, so fetching all that data would be a waste of memory. That's why you don't fetch unnecessary data.

SELECT a.title, a.createdAt
FROM EntityArticle a
ORDER BY a.createdAt DESC
LIMIT 25

$isFirst = true;
foreach ($articles as $article) {
    echo $article->getTitle();
    echo $article->getCreatedAt();

    if ($isFirst) {
        echo $article->getContent(); // Article::content is not loaded so it is transparently loaded 
                                     // for this single article.

        $isFirst = false;
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...