Pattern, Abstract Factory / Factory

Marco Antoniotti marco.antoniotti at unimib.it
Sun Feb 7 07:58:50 UTC 2021


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 <pjb at 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/pro/attachments/20210207/3e346f1c/attachment-0001.html>


More information about the pro mailing list