I think the most important rule when using component is to only use local
state like Timothy stated, i.e. nothings gets def-ed. You could write an
application that a -main function that starts the system and you would
never need a global reference to the system.

In practise however, you do make references to the current system to
support working in the REPL (see README here
<https://github.com/stuartsierra/component/#reloading>) and I also use
references to the system to inspect db state etc in tests, but for that
`let` blocks also work well.

I would recommend to continue playing with the bare metal component for a
while to get an understanding of the concept, after a while I think you
will want something smarter. We're using system-graph
<https://github.com/RedBrainLabs/system-graph> that helps to stop thinking
and managing dependencies and recently we have a built a small layer on top
of that so we even have flexible graphs in a convenient way.

On Tue, Jun 9, 2015 at 8:33 AM, Atamert Ölçgen <mu...@muhuk.com> wrote:

>
>
> On Tue, Jun 9, 2015 at 6:12 AM, Timothy Baldridge <tbaldri...@gmail.com>
> wrote:
>
>> Stuart addresses two anti-patterns in your PRs. Perhaps I can help
>> explain them.
>>
>> Let's say we have a system that looks like this:
>>
>> (defrecord DBConnection [])
>>
>> (defrecord DBLayer [db-connection])
>>
>> (defrecord AppLayer [db-layer])
>>
>> We can construct a system thusly:
>>
>> {:db-connection (->DBConnection ...)
>>  :db-layer (->DBLayer ...)
>>  :app-layer (->AppLayer ...)}
>>
>> And start it up:
>>
>> (def my-system (start-system system-map))
>>
>>
>> First of all, what you need to recognize is that every component now has
>> it's dependencies assoc'ed into the component. So each component should
>> only deal with it's local view of the system:
>>
>> (defrecord AppLayer [db-layer]
>>   IDoStuff
>>   (do-stuff [this]
>>     (print-data (get-data db-layer)
>>                      (get-data2 (:db-layer this)))
>>
>> What should not happen is that the AppLayer should do this:
>>
>> (print-data (:db-layer my-system))
>>
>> If a component does this it now has access to the entire system, and that
>> circumvents one of the reasons component was created, to help improve
>> separation of concerns.
>>
>> In your other example you're doing something like this:
>>
>> (defrecord AppLayer [db-layer]
>>   IDoStuff
>>   (do-stuff [this]
>>      (run-query (:db-conn db-layer) "select foo from bar")))
>>
>> The problem with this is that AppLayer is assuming that the db-layer has
>> a connection to the db. This also violates the separation of concerns.
>> Instead AppLayer should include a db-connection as a dependency if it is
>> needed by the app layer code.
>>
>
> This is also known as The Law of Demeter. (
> http://en.wikipedia.org/wiki/Law_of_Demeter)
>
> - Each unit should have only limited knowledge about other units: only
> units "closely" related to the current unit.
> - Each unit should only talk to its friends; don't talk to strangers.
> - Only talk to your immediate friends.
>
>
>>
>> So that sums up Stuart's two replies. a) don't touch the system from
>> inside a component, the system map is only for starting and stopping the
>> system, and to provide an entry point. b) don't reach into other components
>> from a component
>>
>>
>> Timothy
>>
>> On Mon, Jun 8, 2015 at 9:35 PM, James Reeves <ja...@booleanknot.com>
>> wrote:
>>
>>> My recommendation is to use a closure. So I'd write your example as:
>>>
>>> (defn username-endpoint [{:keys [db]}]
>>>   (routes
>>>    (GET "/:username" [username]
>>>      (let [user (users/get-user db username)]
>>>        (str "<h1>Hello " (:name user) "</h1>")))))
>>>
>>> So you pass your configuration map into the endpoint function, which
>>> returns a handler.
>>>
>>> You can then wrap this in a component:
>>>
>>> (defrecord EndpointComponent [build-routes]
>>>   component/Lifecycle
>>>   (start [component]
>>>     (if (:routes component)
>>>       component
>>>       (assoc component :routes (build-routes component))))
>>>   (stop [component]
>>>     (dissoc component :routes)))
>>>
>>> Incidentally, the above code is taken directly from Duct
>>> <https://github.com/weavejester/duct>, a template and small supporting
>>> library I've written for building component-based web apps.
>>>
>>> I've also written a blog article
>>> <https://www.booleanknot.com/blog/2015/05/22/structuring-clojure-web-apps.html>
>>>  around
>>> general best practice for this type of style.
>>>
>>> - James
>>>
>>>
>>> On 8 June 2015 at 22:51, Dru Sellers <d...@drusellers.com> wrote:
>>>
>>>> So, I guess I am a bit lost, how does someone actually use component? I
>>>> have an application all set up with it and it seems to be working as I
>>>> would expect but Stuart seems to be steering me in a different direction.
>>>>
>>>> https://github.com/stuartsierra/component/pull/35
>>>>
>>>> https://github.com/stuartsierra/component/issues/34
>>>>
>>>> So I'll try and paint a full picture.
>>>> https://gist.github.com/drusellers/8109dce4b9fb19c14ebb
>>>>
>>>> I know compojure and component / reloaded may not play well, but I'm
>>>> trying to figure out how to best use the system var. Am I close, I'd love
>>>> to give back a decent PR to the README.md of the component repo to help
>>>> others as they come along.
>>>>
>>>> -d
>>>>
>>>> --
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Clojure" group.
>>>> To post to this group, send email to clojure@googlegroups.com
>>>> Note that posts from new members are moderated - please be patient with
>>>> your first post.
>>>> To unsubscribe from this group, send email to
>>>> clojure+unsubscr...@googlegroups.com
>>>> For more options, visit this group at
>>>> http://groups.google.com/group/clojure?hl=en
>>>> ---
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Clojure" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>> an email to clojure+unsubscr...@googlegroups.com.
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>>
>>>  --
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To post to this group, send email to clojure@googlegroups.com
>>> Note that posts from new members are moderated - please be patient with
>>> your first post.
>>> To unsubscribe from this group, send email to
>>> clojure+unsubscr...@googlegroups.com
>>> For more options, visit this group at
>>> http://groups.google.com/group/clojure?hl=en
>>> ---
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to clojure+unsubscr...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>
>>
>> --
>> “One of the main causes of the fall of the Roman Empire was that–lacking
>> zero–they had no way to indicate successful termination of their C
>> programs.”
>> (Robert Firth)
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to clojure+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>
>
> --
> Kind Regards,
> Atamert Ölçgen
>
> ◻◼◻
> ◻◻◼
> ◼◼◼
>
> www.muhuk.com
> www.olcgen.com
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to