Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have some code, which I want to present in UML, but I've stuck at one point. Let me tell you something about code's functionality.

I have a workspace in which I can place some Components, select them, delete, add new, move etc. I can also connect them according to some rules (there are different types of Components available). In order to determine if a group of Components can be connected or not, I've implemented some easy mechanism. In this mechanism the following parts appear:

[EDIT: Please note, that "PlausibilityRule" in UML and "ConnectionRule" are the same things - it's my oversight]

ConnectionRule - get the type of connection, and checks if a collection of Components given as a parameter can be connected according to this ConnectionRule.

ConnectionRulesSet - has many rules inside. Client asks a set with rules like this: "according to which rules definied in a set, components given as a parameter, can be connected"? ConnectionRulesSet gives a list of ConnectionRules as a response. A concrete Connection rules set are exposed only throug interface - Client cannot create an instance of a concrete RulesSet.

RulesSetFactory - depending on many circumstances, application can use different ConnectionRulesSets. That's why I've created a factory which gives a proper implemetation of ConnectionRulesSet interface depending on specified circumstances.

And now let's take a look at the Client's code:

// list of components which should be verified in terms of connection plausibility:
List<Component> selectedComponents = ... ;
// Get set of rules for normal conditions:
ConnectionRulesSet setOfRules = RulesSetFactory.getRulesSet(NORMAL_SET);
List<ConnectionRule> fulfilledRules = setOfRules.getFulfilledRules(final selectedComponents);
// Do something with fulfilled rules:
for(PlausibilityRule rule : fulfilledRules){
   addToAvailableRulesList(rule.getConnectionType().getName()); // display names of connetion types...
} 

My problem is, that I'm not sure how to create an UML class diagram for such solution from Client's perspective... How to expose relationships between presented solution and a Client. Client uses actually all: ConnectionRule, RulesSet, RulesSetFactory...

There is one of my ideas below... What do you think? Have you got any better solution?

Sample UML class diagram

share|improve this question
1  
It looks like some of the interface names in your UML diagram don't match up with the explanation in your question? Is PlausibilityRule the same concept as ConnectionRule? If not: a) What is the difference? and b) Where is ConnectionRule (as opposed to ConnectionRulesSet) in the diagram? – Tersosauros Feb 28 at 5:16
    
@Tersosauros Yeah, you are certainly right - PlausibilityRule and ConnectionRule are the same things - my oversight – guitar_freak Feb 28 at 17:35
    
So then, is a ConnectionRulesSet just an aggregation/composition of ConnectionRule's? Or is there more responsibility meant by the ConnectionRulesSet having the behavior to getFulfilledRules? – Tersosauros Feb 28 at 18:58
    
@Tersosauros Actually it aggregates all Rules and, using the getFulfilledRules method, returns only those which are reasonable for components given as a parameter (btw, getFulfilledRules() should take a 'comps' parameter, I guess - it seems that this question was not perfectly prepared before asking :/) – guitar_freak Feb 28 at 22:17
    
So ConnectionRulesSet (which I believe under most OOP naming conventions would/should be "ConnectionRuleSet " - It's one set, of zero or more ConnectionRule's, not ConnectionRules..) - has both a behavioural responsibility (filtering rules), and an aggregation responsibility (being a set of rules)? – Tersosauros Mar 1 at 22:13

Alright, I'm going to give this answer a shot - hopefully I've understood everything correctly!

The Diagram

Firstly, let me apologize in advance for the layout (yUML is nice and quick, but lays large diagrams out strangely sometimes). Class diagram (from yUML.me)

As you can see, there aren't that many changes. But there are a few, namely:

  • Added an aggregation (specifically, a "composition") from ConnectionRuleSet to ConnectionRule.

         This is more clear, I feel, than the returns list of relation in your original diagram (as a ConnectionRuleSet is a set of ConnectionRule's). The container relationship reflects the aggregation responsibility of ConnectionRuleSet, but may not explicitly explain the behavioural responsibility of the getFulfilledRules method.

  • Removed the uses between Client and ConnectionRuleSet.

         Given the uses relation already in-place in-between Client and ConnectionRule directly, adding another uses between Client and ConnectionRuleSet I feel needlessly overcomplicates things. It's clear that a ConnectionRuleSet contains ConnectionRule's (thanks to the composition).

  • Added a Component class to the diagram.

         I'm not 100% sure exactly what a Component is in your domain, however I think it might be worth it to include it in the diagram. After all, it is mentioned in methods in ConnectionRule and ConnectionRuleSet. It is not entirely clear from your question what the relation between Client and Component should be, I've used aggregation as it seems a Client contains many Component's.


Other Diagram Notes

  1. Example concrete classes: I think the example concrete classes, such as ConcreteConnectionRuleSet, ConcreteRule1 and ConcreteRule2, etc add very little to the diagram. I've included them as they were in the original, but I think the diagram would be much simpler without them.

  2. Vector<Component>: Again, included as it was in the original, but I would STRONGLY recommend that you don't tie your design to particular data-structure implementations (this goes for List<Component> too!). Something like Collection<Component>, or at a minimum an IList<Component> would be much better here.


Feel free to go on to yUML and edit the diagram... Below is the code yUML code I used to make it:

[«interface»;RuleSetFactory|+ getRuleSet(rulseSetType : enum)]-.-                 «instantiates»-.->[«interface»;ConnectionRuleSet|getFulfilledRules(comps : List≤Component≥)]
[«interface»;ConnectionRuleSet]++-[«interface»;ConnectionRule|+ getConnectionType();+ isFulfilledForComponents(comps : Vector≤Component≥)]
[«interface»;ConnectionRule]<-.-   uses-.-[Client]
[Client]<>-?-[Component]
[Client]-.-requests       RuleSet from-.->[«interface»;RuleSetFactory]
[«interface»;ConnectionRuleSet]^.=[ConcreteConnectionRuleSet]
[«interface»;ConnectionRule]^-.=[ConcreteRule1]
[«interface»;ConnectionRule]^-.=[ConcreteRule2]
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.