> Am 07.02.2021 um 09:25 schrieb Hans Hübner <hans.hueb...@gmail.com>:

> The applicability of dependency injection really depends on the complexity of 
> the framework that is being talked about.  In simple, and in particular in 
> framework-less systems, one does not really need a framework-specific, 
> configurable, run-time linking component.  Most Lisp systems do not actually 
> depend on a framework, and Lisp - as a dynamic language - provides for plenty 
> of run-time features that can be used to achieve what is the magic sauce in 
> dependency injection frameworks.  One may want to standardize how component 
> linkage is performed in a large Lisp system, of course, but the challenges 
> would be different as much of the tooling to perform the actual work is 
> available right away.

Well. There are plenty libraries out there for Common Lisp.
The question one has to ask. Do I use them directly, creating a source code 
dependency, like a web server. Or do create and use an abstraction in order to 
be able to replace it. In the sense of ‚keeping libraries at arms length‘.
For small application this is of course overkill.
But I would be interested what the alternatives in Lisp are.
In some Common Lisp project I did last year I had separated the protocols from 
the implementations.
Structured the ASDF loading in a sequence that the protocols are loaded first, 
then a layer that uses those protocols is loaded, and finally the concrete 
implementations are loaded.
This worked fine. But I just came up with this and I’m not sure if there are 
better alternatives.

> 
> The same can be said about many of the patterns that are used in the OO and 
> Java world, of course.  They often provide solution architectures to problems 
> that are hard to solve given the constraints of - in particular - Java, and 
> for which trivially easy solutions can be devised in Lisp on the fly without 
> having to resort to a named pattern.

That’s what I’m trying to figure out.
Implementing Abstract Factory in Java (or Scala for what I do) is relatively 
bloated.
We figured so far that make-instance `clazz-symbol is probably the simplified 
version to do that in Common Lisp, with maybe a little bit of boiler-plate.



Manfred

> 
> Am So., 7. Feb. 2021 um 08:59 Uhr schrieb Marco Antoniotti 
> <marco.antonio...@unimib.it>:
> 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


Reply via email to