
Αυτό είναι επίσης ένα ερώτημα που έθεσα σε ένα σχόλιο σε ένα από τα Miško Hevery για [συνομιλίες google](http://misko.hevery.com/2008/11/11/clean-code-talks-dependency-injection/) που ασχολούνται με την εξάρτηση της ένεσης, αλλά θάφτηκαν στα σχόλια.


Αναρωτιέμαι πώς μπορεί το βήμα του εργοστασίου / κατασκευαστή της καλωδίωσης των εξαρτήσεων μεταξύ τους μπορούν να εργαστούν σε C ++.


Δηλ έχουμε μια τάξη Α που εξαρτάται από B. Η οικοδόμος θα διαθέσει Β στο σωρό, να περάσει ένα δείκτη προς Β σε κατασκευαστή Α, ενώ επίσης την κατανομή στο σωρό και να επιστρέψει ένα δείκτη προς Α


Ποιος καθαρίζει μετά; Είναι καλό να αφήσει ο οικοδόμος καθαρίσει μετά το κάνει; Φαίνεται να είναι η σωστή μέθοδος δεδομένου ότι στη συζήτηση που λέει ότι ο οικοδόμος θα πρέπει να αντικείμενα ρυθμίσεων που αναμένεται να έχουν την ίδια διάρκεια ζωής ή τουλάχιστον οι εξαρτήσεις έχουν μεγαλύτερη διάρκεια ζωής (έχω και μια ερώτηση σχετικά με αυτό). Αυτό που θέλω να πω στον κώδικα:



```
class builder {
public:
    builder() :
        m_ClassA(NULL),m_ClassB(NULL) {
    }
    ~builder() {
        if (m_ClassB) {
            delete m_ClassB;
        }
        if (m_ClassA) {
            delete m_ClassA;
        }
    }
    ClassA *build() {
        m_ClassB = new class B;
        m_ClassA = new class A(m_ClassB);
        return m_ClassA;
    }
};

```

Τώρα αν υπάρχει μια εξάρτηση που αναμένεται να διαρκέσει περισσότερο από τη διάρκεια ζωής του αντικειμένου που την έγχυση σε (ας πούμε ClassC είναι ότι η εξάρτηση) Καταλαβαίνω ότι πρέπει να αλλάξουμε τον τρόπο κατασκευής σε κάτι σαν:



```
ClassA *builder::build(ClassC *classC) {
    m_ClassB = new class B;
    m_ClassA = new class A(m_ClassB, classC);
    return m_ClassA;
}

```

Ποια είναι η προτιμώμενη προσέγγιση σας;

 
Εξάρτηση ένεση σε C ++
======================



Αυτή η συζήτηση είναι για Java και ένεση εξάρτησης.  



Στην C ++ προσπαθούμε **ΔΕΝ** να περάσει RAW δείκτες γύρω. Αυτό οφείλεται στο γεγονός ότι ένα RAW δείκτης δεν έχουν σημασιολογία ιδιοκτησίας που συνδέονται με αυτό. Αν δεν έχετε την κυριότητα τότε δεν ξέρουμε ποιος είναι υπεύθυνος για τον καθαρισμό του αντικειμένου.


Θεωρώ ότι οι περισσότεροι από την ένεση εξάρτηση του χρόνου γίνεται μέσω αναφορών σε C ++.   

Στις σπάνιες περιπτώσεις όπου θα πρέπει να χρησιμοποιήσετε τους δείκτες, τα τυλίγουμε σε [std :: unique\_ptr <>](http://www.cplusplus.com/reference/memory/auto_ptr/) ή [std :: shared\_ptr <>](http://www.cplusplus.com/reference/memory/shared_ptr/) , ανάλογα με το πώς θέλετε να διαχειριστείτε την ιδιοκτησία.   

Σε περίπτωση που δεν μπορείτε να χρησιμοποιήσετε C ++ 11 χαρακτηριστικά, χρησιμοποιήστε std :: auto\_ptr <> ή να ενισχύσει :: shared\_ptr <>.


Θα ήθελα επίσης να επισημάνω ότι η C ++ και Java στυλ του προγραμματισμού είναι σήμερα τόσο αποκλίνουσες ότι η εφαρμογή του στυλ μιας γλώσσας στην άλλη, θα οδηγήσει αναπόφευκτα σε καταστροφή. 

 

Αυτό είναι ενδιαφέρον, DI σε C ++ χρησιμοποιώντας τα πρότυπα:


<http://adam.younglogic.com/?p=146>


Νομίζω ότι ο συγγραφέας έχει κάνει τις σωστές κινήσεις ώστε να μην μεταφράσει Java DI σε C ++ πολύ κυριολεκτικά. Αξίζει να το διαβάσετε.

 

Έχω πρόσφατα τσίμπημα από το έντομο DI. Νομίζω ότι λύνει πολλά προβλήματα πολυπλοκότητας, ειδικά το αυτοματοποιημένο μέρος. Έχω γράψει ένα πρωτότυπο το οποίο σας επιτρέπει να χρησιμοποιήσετε DI σε μια όμορφη C ++ τρόπο, ή τουλάχιστον έτσι νομίζω. Μπορείτε να ρίξετε μία ματιά στο παράδειγμα κώδικα εδώ: <http://codepad.org/GpOujZ79>


Τα πράγματα που προφανώς λείπει: δεν υπάρχει οριοθέτηση του πεδίου εφαρμογής, χωρίς σύνδεση της διεπαφής με την εφαρμογή. Το τελευταίο είναι πολύ εύκολο να λυθεί, ο πρώην, δεν έχω ιδέα.


Θα ήμουν ευγνώμων αν κάποιος εδώ έχει μια γνώμη σχετικά με τον κώδικα.

 

Χρησιμοποιήστε RAII. 


Παράδοση σε πρώτες δείκτη σε κάποιον είναι η ίδια με την παράδοση τους ιδιοκτησία. Αν αυτό δεν είναι αυτό που θέλετε να κάνετε είναι, θα πρέπει να τους δώσουμε κάποιο είδος πρόσοψης που ξέρει πώς να καθαρίσει το εν λόγω αντικείμενο.


shared\_ptr <> να το κάνετε αυτό? το δεύτερο επιχείρημα του κατασκευαστή του μπορεί να είναι ένα αντικείμενο λειτουργία που ξέρει πώς να διαγράψετε το αντικείμενο.

 

Με βάση τη δική μου εμπειρία, το καλύτερο είναι να υπάρχουν σαφείς κανόνες ιδιοκτησίας. Για τα μικρά συγκεκριμένα αντικείμενα, είναι καλύτερο να χρησιμοποιήσετε άμεσα αντίγραφο για να αποφεύγεται η διασταυρούμενη εξάρτησης.


Μερικές φορές σταυρό εξάρτηση είναι αναπόφευκτη, και δεν υπάρχει σαφής ιδιοκτησίας. Για παράδειγμα, (m) περιπτώσεις Α δικό (n) περιπτώσεις Β, και ορισμένες περιπτώσεις Β μπορεί να ανήκει πολλαπλές As. Σε αυτή την περίπτωση, η καλύτερη προσέγγιση είναι να εφαρμοστεί καταμέτρηση αναφορά στο Β, με τον τρόπο παρόμοιο με μέτρηση αναφοράς COM. Όλες οι λειτουργίες που πάρει στην κατοχή του Β * πρέπει να αυξήσει τον αριθμό αναφοράς πρώτα, και να μειώσει το κατά την απελευθέρωση της κατοχής.


Επίσης, αποφύγετε τη χρήση ώθηση :: shared\_ptr, δεδομένου ότι δημιουργεί ένα νέο τύπο (shared\_ptr και Β * να γίνουν δύο διαφορετικά είδη). Βρήκα ότι φέρνει πιο πονοκεφάλους, όταν μπορώ να προσθέσω μεθόδους.

 

Στη C ++, συνήθως, όταν γίνονται τα πράγματα σωστά, δεν χρειάζεται να γράψω καταστροφείς καθόλου στις περισσότερες περιπτώσεις. Θα πρέπει να χρησιμοποιείτε έξυπνες δείκτες για να διαγράψετε τα πράγματα αυτόματα. Νομίζω, οικοδόμος δεν μοιάζει με τον ιδιοκτήτη των περιπτώσεων ClassA και classB. Αν δεν σας αρέσει να χρησιμοποιείτε έξυπνη δείκτες, θα πρέπει να σκεφτείτε το χρόνο αντικείμενα ζωή και τους ιδιοκτήτες τους.

 

Τα πράγματα έγιναν πιο περίπλοκα αν δεν εγκατασταθούν για το ζήτημα της ιδιοκτησίας, μια για πάντα. Θα πρέπει απλώς να αποφασίσει για την εφαρμογή σας, αν είναι δυνατόν εξαρτήσεις ζουν περισσότερο από τα αντικείμενα που εγχέεται.  



Προσωπικά θα ήθελα να πω όχι: το αντικείμενο στο οποίο η εξάρτηση εγχέεται θα καθαρίσει μετά. Προσπαθώντας να το κάνει μέσα από τον κατασκευαστή σημαίνει ότι ο κατασκευαστής θα πρέπει να ζουν περισσότερο από ό, τι τόσο την εξάρτηση και το αντικείμενο στο οποίο εγχέεται. Αυτό προκαλεί περισσότερα προβλήματα από όσα επιλύει, κατά τη γνώμη μου, επειδή ο κατασκευαστής δεν εξυπηρετεί πλέον χρήσιμο σκοπό, μετά την ολοκλήρωση της κατασκευής με την ένεση εξάρτηση.

 

Μπορείτε επίσης να ελέγξετε την [**έγχυση FFEAD εξάρτηση**](http://code.google.com/p/ffead-cpp/wiki/DependencyInjection) . Παρέχει DI στις γραμμές της Άνοιξης της JAVA και έχει μια διακριτική τρόπο αντιμετώπισης των πραγμάτων. Έχει επίσης πολλά άλλα σημαντικά χαρακτηριστικά, όπως το ενσωματωμένο **AJAX υποστήριξη, προβληματισμού, Serialization, C ++ Διερμηνέας, Business εξαρτημάτων για C ++, ORM, Μηνύματα, Web-Services, το νήμα-Πισίνες και ένα Application Server** που υποστηρίζει όλα αυτά τα χαρακτηριστικά.

 