Define positive dependency list instead of what's forbidden

4 views
Skip to first unread message

Oliver Gierke

unread,
Aug 4, 2008, 9:11:22 AM8/4/08
to architecture-rules-users
One more time its me. There's another thing I've discovered. To me it
feels quite strange to define, what is forbidden instead of what is
allowed. The approach of defining violations generates a lot of false
positives if not defined correctly. I think it would be easier to do
not allow any dependency by default - generating false negatives - and
the step by step defining what is allowed and what not.

To my mind this much more fits into the natural process of
architecture definitions. There you don't define "subsystem X is not
allowed to communicate with Y, Z". Rather you define the allowed
dependencies. Furthermore adding a package to the project
automatically makes it accessible to all other packages by default. So
I'd have to define the new package at possibly all minus one rules to
be invalid.

Of course you would need to allow common allowed dependencies (like
java.lang.util) that are transparently added to all rules, as you
would have to define them on every rule otherwise.

Hope you are not overwhelmed with critique. I just see the
potential ;). And would like to help, if you like.

Regards,
Ollie

PS: Just extracted the post from another thread to exchange thoughts
on that directly. I've posted an issuer here (http://code.google.com/p/
architecturerules/issues/detail?id=53) and provided a quick POC hack
to demonstrate what I'd like to see. Going to implement a little
cleaner version, the next days.

Mike Nereson

unread,
Aug 4, 2008, 11:08:46 AM8/4/08
to architecture...@googlegroups.com

One more time its me. There's another thing I've discovered. To me it
feels quite strange to define, what is forbidden instead of what is
allowed. The approach of defining violations generates a lot of false
positives if not defined correctly. I think it would be easier to do
not allow any dependency by default - generating false negatives - and
the step by step defining what is allowed and what not.
I have two thoughts on why it is better to provide the negatives rather than the positives.

First, is the java runtime. I don't think we want our users to have to define all of the or any of the java packages, such as java.lang, java.util etc.

Also, I was am only thinking within the scope of my project and it's packages. I want to keep my com.project.layer from com.project.otherlayer.


To my mind this much more fits into the natural process of
architecture definitions. There you don't define "subsystem X is not
allowed to communicate with Y, Z". Rather you define the allowed
dependencies. 
This sounds good. Perhaps architecture rules can be extended to support the definition of modules rather than packages. Imagine something like

<module id="module1">
  <packages>
    <package>com.company.project.module1</package>
    <package>com.company.project.module1..*</package>
  </packages>
  <dependencies>
    <dependency>module2</dependency>
  </dependencies>
<module>
 
<module id="module2">
  <packages>
    <package>com.company.project.module2</package>
    <package>com.company.project.module2..*</package>
  <packages>
    <dependencies/>
<module>

This might be a staring point for new architecture rules functionality. Thoughts?
Furthermore adding a package to the project
automatically makes it accessible to all other packages by default. So
I'd have to define the new package at possibly all minus one rules to
be invalid.
If you have ..project.web, ..project.service, ..project.dao and you define your rules with wildcards, then adding a new package to one of these packages would be included in the rules.
 
I appreciate the critique and comments. But this particular issue would completely turn architecture rules around. I'm not sure we want to do that at this point. However, if other users have similar comments, then it is something that we could investigate further.

Ollie, these are my views on the project. Like I said, I'd like to hear other's thoughts. Keep the comments coming.

~ Mike Nereson

Oliver Gierke

unread,
Aug 4, 2008, 1:21:47 PM8/4/08
to architecture-rules-users
No need to apologize, Mike ;).

On Aug 4, 5:08 pm, "Mike Nereson" <mikenere...@gmail.com> wrote:
> One more time its me. There's another thing I've discovered. To me it> feels quite strange to define, what is forbidden instead of what is
> > allowed. The approach of defining violations generates a lot of false
> > positives if not defined correctly. I think it would be easier to do
> > not allow any dependency by default - generating false negatives - and
> > the step by step defining what is allowed and what not.
>
> I have two thoughts on why it is better to provide the negatives rather than
> the positives.
>
> First, is the java runtime. I don't think we want our users to have to
> define all of the or any of the java packages, such as java.lang, java.util
> etc.

This is why I gave the <commons> element a go. These dependencies are
automatically added to all rules and thus do not need to require
multiple definitions. Maybe one could simply call the element <ignore>
and do not regard these packages at all?!

> <module id="module1">
>   <packages>
>     <package>com.company.project.module1</package>
>     <package>com.company.project.module1..*</package>
>   </packages>
>   <dependencies>
>     <dependency>module2</dependency>
>   </dependencies>
> <module>
>
> <module id="module2">
>   <packages>
>     <package>com.company.project.module2</package>
>     <package>com.company.project.module2..*</package>
>   <packages>
>     <dependencies/>
> <module>

This is the way SonarJ builds its architecture model. I could imagine
this as a further step but the simple turnaround was much easier to
implement as a POC ;).

> If you have ..project.web, ..project.service, ..project.dao and you define
> your rules with wildcards, then adding a new package to one of these
> packages would be included in the rules.

I especially pay attention not to let single packages have
dependencies to many other packages. This leads to package structures
that have much less allowed dependencies, that forbidden. Imagine a
package having one allowed dependency but 20 not allowed. Playing
around with the POC I think the configuration amount has reduced
significantly.

The case of adding packages and breaking rules can be illustrated a
little better imagining the situation of adding an additional library.
Adding Hibernate to your project would require you to reconfigure all
your rules except the one describing the DAO layer not to allow to
acces hibernate. Doing this instead of simply declaring "Only DAO is
allowed to use Hibernate" seems weird to me.

I think i don't need to elaborate on this much more, as I think you
got my point. I hope to here opinions from other users as well ;).

Regards,
Ollie

Mike Nereson

unread,
Aug 4, 2008, 1:54:45 PM8/4/08
to architecture...@googlegroups.com
This is why I gave the <commons> element a go. These dependencies are
automatically added to all rules and thus do not need to require
multiple definitions. Maybe one could simply call the element <ignore>
and do not regard these packages at all?
 
We could provide a default list of common java packages in addition to allowing the user to add and remove commons packages from the common list if we did this.

I personally would always use the violations list, rather than an allowed list. But I can see that you would find it easier and require less configuration if you had an accepted list. Is there someway that we can do both? Can we do a violations configuration element OR an dependencies configuration element? In the case where violations are provided, we find look for packages that are in the violations list and throw the exception when one is found, and in the case of the dependencies are provided, we look for packages NOT included in the dependency list?

Can this be implemented and documented in a way so as not to confuse users?

~ Mike Nereson
Reply all
Reply to author
Forward
0 new messages