2009-02-11 8 views
1

Je tente de conceptualiser le motif de conception de Singleton (qua Java) dans OCaml et j'ai déjà vu des exemples de foncteurs ou de modules, que je n'utilise pas dans une preuve de concept du travail du GoF. Au fond, je voudrais recréer les fonctionnalités suivantes à l'aide OCaml:Implémentation de Singleton classique dans OCaml

public class Singleton 
{ 
private static Singleton UniqueInstance; 
private Singleton(){} 
public static Singleton getInstance() 
{ 
    if(UniqueInstance==null)UniqueInstance=new Singleton(); 
    return UniqueInstance; 
} 
} 

Est-ce possible sans modules ou foncteurs?

Répondre

3

Les objets dans Ocaml ne peuvent pas avoir de méthodes statiques/globales. Vous pouvez essayer, Immediate objects. Attention, je pense que vous pouvez toujours faire obj.copy pour obtenir une copie de l'objet, et chaque fois qu'ils sont évalués, ils renvoient un nouvel objet (donc vous ne pouvez pas passer des paramètres à l'objet, vous pouvez, avec un peu d'encapsulation et un booléen, mais maintenant vous avez affaire à des modules). Bien sûr, si vous avez seulement quelque chose comme il exemple,

let p = object 
    val mutable x = 0 
    method get_x = x 
    method move d = x <- x + d 
end 

p serait évaluée une fois, et vous accéderiez que chaque fois. Bien sûr, la copie de p # gâcherait des choses pour vous. Les modules sont la manière d'aller ici. Les fonctions OO d'Ocaml ne sont pas aussi puissantes que les autres langues. Ce n'est bien sûr pas le but du projet, c'est le système de module qui est très puissant,. Les modules sont (global) singletons. Il n'y a vraiment rien que vous avez à écrire pour les construire. Ils sont implicitement dans la langue. Par exemple, que diriez-vous de se connecter à un fichier:

---logging.ml 
(* default channel to log *) 
let log_channel = ref stdout 

(* set the log to a channel *) 
let set_log_chan chan = log_channel := chan 

(* timestamp of log -- kinda heavy weight, but just for kicks *) 
let get_log_prequel() = 
    let time = Unix.localtime (Unix.time()) in 
    (* format the time data into "y/m/d - h:m:s" format *) 
    Printf.sprintf "%d/%02d/%02d - %02d:%02d:%02d" 
        (time.Unix.tm_year+1900) time.Unix.tm_mon time.Unix.tm_mday 
        time.Unix.tm_hour time.Unix.tm_min time.Unix.tm_sec 

(* log a string to the channel *) 
let log_string str = 
    output_string (!log_channel) ((get_log_prequel())^":\t"^str^"\n") 

---logging.mli 
set_log_chan : in_channel -> unit 
log_string : string -> unit 

Je pense que vous obtenez le point ici. Le singleton est implicite, n'est-ce pas? Il n'y a pas vraiment d'instanciation comme dans les objets - mais c'est un peu ce que vous voulez dans un singleton. Vous commencez simplement à l'utiliser dans d'autres fichiers comme, Logging.log_string "parsed file "^file_name^" successfully.", et cetera, n'importe où et vous utilisez toujours le même canal.

Avec les foncteurs, vous pouvez composer vos modules pour ajouter de la variété. Comme spécifier un module/fonction pour générer un prequel pour la sortie, et cetera.

+0

J'ai vu de nombreuses références citant des modules sont la voie à suivre. Qu'est-ce qu'un exemple d'implémentation OCaml de Singleton utilisant des modules? Applique-t-il toutes les caractéristiques de Singleton (par exemple constructeur privé, application d'instance unique, etc.)? Merci! –

+0

Existe-t-il un moyen de remplacer la méthode de copie de l'objet et Oo.copy? Malheureusement, j'ai besoin d'utiliser les constructions d'objets d'OCaml, donc les objets immédiats peuvent être ma seule route. Avez-vous d'autres idées sur la façon de faire cela? Merci! –

+0

Je ne crois pas que vous pouvez remplacer les fonctions de copie - bien, pas sans méta-ocaml (je crois), ou peut-être camlp4 (je crois). Je suppose que la seule recommandation ici, ne pas appeler les fonctions de copie :) – nlucaroni

4

Pouvez-vous expliquer pourquoi la solution du module ne fonctionne pas pour vous? Les modules sont vraiment la façon naturelle de faire ce que vous feriez avec un singleton dans d'autres langues. En règle générale, les modèles de style GOF sont largement non pertinents dans OCaml. En effet, les objets sont largement non pertinents dans OCaml. Les gens de milieux OO pensent souvent qu'ils devraient commencer en utilisant les fonctionnalités OO dans OCaml, mais c'est une erreur. La plupart des problèmes résolus avec des objets dans d'autres langages sont résolus avec un polymorphisme paramétrique, des types de données algébriques et des modules dans OCaml. Les foncteurs sont un sujet un peu plus avancé, et les objets sont loin d'être là. Vous ne devez pas toucher au système objet tant que vous n'êtes pas un utilisateur accompli du reste de la langue.