Risposta 1: Può avere senso vincolare la classe alla presenza di un applicativo, tanto più che è il suo wrapper di lancio. Ma dipense dal design complessivo dell'applicazione. E da che punto di vista vuoi privilegiare.
Risposta 2: Controllare che cosa con le direttive di compilazione? Vuoi lincare l'eseguibile dentro il tuo? Allora non vincoli nulla alla presenza nel file system, stai "inglobando" un'applicazione. In Java mi vengono in mente un paio di trucchetti per farlo, ma con il linker del gcc, non ho idea su come iniziare. Figurati del risultato finale ;)
In generale.
Allora ti darei un consiglio spicciolo.
Non fare una classe che fa tutto, perderesti il controllo del codice abbastanza velocemente in situazioni particolarmente eterogenee.
Fai un classe che funga da facade, questa la "connetti" alla classe wrapper. Ogni classe wrapper specifica implementa un'interfaccia o estende una classe astratta che da a disposizione i metodi base per operare le cose che ti interessano.
Come operare la connessione si può usare qualche altro pattern, quello che mi viene in mente è il factory method, in questo modo l'applicazione conosce molti meno dettagli del tuo driver.
Sempre per "parlare".
TDriverFactory = class(TObject)
public
class function getBackupDriver : IBackUpDriver;
end;
Dentro questa funzione metti tutte le cose che ti interessano per il riconoscimento del sistema operativo.
// Importa dai file inc la funzione getMachineDipendentBackUpDriver.
{$IFDEF WINDOW}
{$INCLUDE BackUp.Windows.inc}
{$ENDIF}
{$IFDEF LINUX}
{$INCLUDE BackUp.Linux.inc}
{$ENDIF}
{$IFDEF MAC}
{$INCLUDE BackUp.MAC.inc}
{$ENDIF}
{$IFDEF NEW-OS-BY-NOMORE}
{$INCLUDE BackUp.NEW-OS-BY-NOMORE.inc}
{$ENDIF}
class function TDriverFactory.getBackupDriver : IBackUpDriver;
begin
result := getMachineDipendentBackUpDriver;
end;
Ti fai tutti le classi dentro varie unit, in modo da lasciare "pulito" da millanta IFDEF.
Sai che mi piace il codice il più pulito possibile.
;)
Risposta 2: Controllare che cosa con le direttive di compilazione? Vuoi lincare l'eseguibile dentro il tuo? Allora non vincoli nulla alla presenza nel file system, stai "inglobando" un'applicazione. In Java mi vengono in mente un paio di trucchetti per farlo, ma con il linker del gcc, non ho idea su come iniziare. Figurati del risultato finale ;)
Niente link, con le direttive di compilazione avevo intenzione di controllare la presenza del binario.
Qualcosa tipo:
constructor TMyBackup.Create(AOwner: TComponent);
function Test_rsync_binary
begin
{$IFDEF LINUX}
...
result :=
{$ENDIF}
{$IFDEF WINDOW}
...
result :=
{$ENDIF}
...
end;
begin
if not Test_rsync_binary then
raise exception.Create('unable to find rsync binary!');
inherited Create(AOwner);
end;
Il problema è che per rilasciare i sorgenti:
[windows]
ho il problema di un setup aggiuntivo di cwRsync: stavo quasi pensando di includere cwRsync come file di risorse e, nel momento del Create, scompatto tutto e lo rendo disponibile; certo che così appesantisco un po' i sorgenti ma almeno chi vorrà usare questa classe sotto win avrà tutto pronto all'uso (anche per la distribuzione finale)
[linux]
potrei provare a testare ed eventualmente richiedere presenza del pacchetto rsync