Per un problema particolare nell'architettura di un'applicazione su cui sto lavorando, le interfacce sembrano essere una buona soluzione. Nello specifico, alcuni "oggetti business" dipendono da una serie di impostazioni estratte dal database nell'app reale. Lasciando che questi oggetti business richiedano un'interfaccia (tramite Inversion of Control) e consentendo a un oggetto centrale TDatabaseSettings
di implementare tali interfacce, consente un migliore isolamento e, quindi, un collaudo dell'unità molto più semplice.Bypassare (disabilitare) il conteggio dei riferimenti di Delphi per le interfacce
Tuttavia, in Delphi, le interfacce sembrano venire con, in questo caso, un bonus spiacevole: il conteggio dei riferimenti. Questo vuol dire che se faccio qualcosa di simile:
type
IMySettings = interface
function getMySetting: String;
end;
TDatabaseSettings = class(..., IMySettings)
//...
end;
TMyBusinessObject = class(TInterfacedObject, IMySettings)
property Settings: IMySettings read FSettings write FSettings;
end;
var
DatabaseSettings: TDatabaseSettings;
// global object (normally placed in a controller somewhere)
//Now, in some function...
O := TMyBusinessObject.Create;
O.Settings := DatabaseSettings;
// ... do something with O
O.Free;
Sull'ultima riga (O.Free
), la mia globale DatabaseSettings
oggetto è ora anche liberato, dal momento che l'ultimo riferimento di interfaccia ad esso (che è stata contenuta in O
) è persa !
Una soluzione sarebbe quella di memorizzare l'oggetto "globale" DatabaseSettings
con un'interfaccia; un'altra soluzione sarebbe quella di ignorare il meccanismo di conteggio dei riferimenti per la classe TDatabaseSettings
, quindi posso continuare a gestire lo DatabaseSettings
come un oggetto normale (che è molto più coerente con il resto dell'app).
Quindi, in sintesi, la mia domanda è: come disattivare il meccanismo di conteggio dei riferimenti dell'interfaccia per una particolare classe?
Sono stato in grado di trovare alcune informazioni che suggerisce sovrascrivendo i metodi IInterface
_AddRef
e _Release
per la classe (TDatabaseSettings
nell'esempio); qualcuno lo ha mai fatto?
Oppure diresti che non dovrei farlo (confondendo? Solo una cattiva idea?), E trovare una soluzione diversa al problema architettonico?
Grazie mille!
Grazie mille per la risposta molto ampia, è molto apprezzata! Sì, probabilmente dovrei pensare un po 'di più prima di passare al buio del percorso di disattivazione del conteggio dei riferimenti. – onnodb
Ok, l'ho provato in D2009 e ha funzionato come un fascino ;-). –
Ho ragione che il tuo esempio non disabilita completamente il conteggio dei riferimenti, ma invece fa partire il conteggio dei riferimenti a 1? Immagino che potresti anche farlo chiamando esplicitamente "TMyInterfacedObject._AddRef" subito dopo la creazione dell'oggetto, e poi facendo un "_Release" dove normalmente chiameresti "Libero"? – onnodb