OK. procedure foo is x : Integer := 42; begin ... end
Now foo depends on the hardwired '42' (as is should, one may argue :) ). And we are not even talking about "classes" or Lisp here. Have I boiled down to the essentials? How do you do the rolling eyes emoticon? All the best Marco On Sat, Feb 6, 2021 at 10:50 PM Pascal Bourguignon <p...@informatimago.com> wrote: > Le 06/02/2021 à 22:37, Manfred Bergmann a écrit : > > You have a class. This class uses some other class. > > But by using or creating an instance of this other class directly you > create a dependency on something concrete. > > That’s not what you want, because you might want to replace this with > something else if required. For example with a mock or fake implementation > in a test. > > ‚Dependency injection‘ allows you to declare this dependency with just > an interface/protocol and have some other facility (the dependency > injection framework) ‚inject‘ a concrete object at run-time. > > A similar thing could certainly be done by just using a constructor > parameter (strategy pattern). > > But I think the important part here is the dependency on just an > interface and not on a concrete implementation. For flexibility. > > > With some code: > > ;;;------------------------------------------------------------ > > (defclass used () > ()) > > (defmethod used-stuff ((self used)) > 'stuff) > > ;;; --- > > (defclass user () > ((used :reader used))) > > (defmethod initialize-instance :after ((self user) &key &allow-other-keys) > (setf (slot-value self 'used) (make-instance 'used #|OOPS, > Dependency!|#))) > > (defmethod user-stuff ((self user)) > ;; Not a real dependency on the used class, > ;; it's a dependency on the used-stuff generic function (interface). > (used-stuff (used self))) > > ;;; --- > > (defclass client () > ()) > > (defmethod create-user ((self client)) > ;; The class client depends directly on the user class, > ;; and indirectly on the used class. > (make-instance 'user)) > > > ;;;------------------------------------------------------------ > > (defclass used () > ()) > > (defmethod used-stuff ((self used)) > 'stuff) > > ;;; --- > > (defclass user () > ((used :initarg :used :reader used))) > > ;; The user class has no more any dependency on the used class. > > (defmethod user-stuff ((self user)) > ;; Not a real dependency on the used class, > ;; it's a dependency on the used-stuff generic function (interface). > (used-stuff (used self))) > > ;;; --- > > (defclass client () > ()) > > (defmethod create-user ((self client)) > ;; The class client depends explicitely on the user and used classes. > ;; But now, the class user doesn't depend directly on the used class; > ;; this dependency is injected by the client into the user classe: > (make-instance 'user :used (make-instance 'used))) > > > ;;;------------------------------------------------------------ > > ;; Notably if the client wants the user to use another used class: > > (defclass variant-used (used) > ()) > (defmethod used-stuff ((self variant-used)) > 'variant-stuff) > > (defmethod create-user ((self client)) > ;; only the client needs to be changed; the user class won't know > ;; the difference: > (make-instance 'user :used (make-instance 'variant-used))) > > > -- > __Pascal Bourguignon__ > > -- Marco Antoniotti, Associate Professor tel. +39 - 02 64 48 79 01 DISCo, Università Milano Bicocca U14 2043 http://bimib.disco.unimib.it Viale Sarca 336 I-20126 Milan (MI) ITALY