3

So I was given a task of making a class diagram for a bicycle. I know what a class diagram is and the concepts behind one.

The requirement is that the bike can brake, turn or speed up. Now to me, a bike has three major components: the brake system, drive system and steering system. And each system has each own activators for actions: a brake handle, a pedal and a handlebar.

For my bike to actually brake, I need to go through the brake lever to trigger my brake system (pass data on how hard the lever is squeezed from the lever to the brake system). Same for the other two systems as well. This is what I've come up with so far: enter image description here

My question: Is there a better way to illustrate the connection between the activators and the systems they're supposed to pass data to?

Christophe
  • 74,672
  • 10
  • 115
  • 187
Lee Merlas
  • 141
  • 3
  • Does the system work in isolation, or are there external issues that can change it? Some of the possibilities include crashes (hit a curb, rock, pothole; hit by a vehicle), mechanical failures (flat tire, broken brake cable or caliper, chain derailment), and effects of terrain (up hill). – 1201ProgramAlarm Nov 24 '19 at 03:08
  • @1201ProgramAlarm oh I haven't mentioned my constraints, my bad. The situations is that I just have a bike, and I can brake, turn or speed up. It works in isolation, so to speak. – Lee Merlas Nov 24 '19 at 03:11
  • @LeeMerlas I dared to add on of your comment to the question to clarify, and tried to make the title more specific, so that the question can help other people who have similar problems (and browse through the titles). Can you check if it's ok for you? – Christophe Nov 24 '19 at 13:42
  • @Christophe Yes it's perfectly fine, glad you did that actually. Wasn't too sure of the title myself. – Lee Merlas Nov 24 '19 at 14:17

2 Answers2

4

When it comes to class design, always bear in mind that it is less about mirroring the real world objects and more about organizing your thoughts and reducing complexity behind a use-case like brake(). This is generally achieved by reducing levels into a more flat organization. Also, special components like BrakeLever should not know about general components like BrakeSystem.

I would use more composition. Bike should have-a BrakeSystem. BrakeSystem should have-a Brakes and BrakeLever. BrakeLever should be a public property of BrakeSystem. BrakeLever should have a onPull event that BrakeSystem listens to with its private handleBrakeLeverPull() method. handleBrakeLeverPull() can call the private reduceRPM() method. reduceRPM() then uses Wheels setWheelSpeed(). DriveSystem and SteerSystem in an analogous manner.

Ozan
  • 360
  • 1
  • 9
  • "BrakeSystem should also expose BrakeLever" can you expound more on how you would do that? – Lee Merlas Nov 24 '19 at 07:32
  • I edited my answer, `BrakeLever` should be a public property of `BrakeSystem` – Ozan Nov 24 '19 at 07:36
  • Would aggregation still work? Correct me if I'm wrong, but if I use composition, it would mean that the `BrakeSystem` would not exist if `Bicycle` does not exist as well, right? – Lee Merlas Nov 24 '19 at 07:44
  • That is the idea. Why should `BrakeSystem`exist outside of `Bike`? – Ozan Nov 24 '19 at 07:49
  • Oh, I see where I went wrong now. But then, I can use aggregation on `BrakeLever` and `Brake` right? Since they can exist outside the system. – Lee Merlas Nov 24 '19 at 07:51
  • The `BrakeLever` should be owned by exactly one component. This can be `BrakingSystem` or another. Other components can know `BrakeLever` by aggregation, but generally the number of these relations should be as low as possible. – Ozan Nov 24 '19 at 07:59
  • Hmm I see. Thank you, I'll try to apply your answer now. – Lee Merlas Nov 24 '19 at 08:04
  • 1
    @LeeMerlas: This is a contrived example, so it doesn't make sense to overanalyze it in this way. Whether something is an aggregation or a composition entirely depends on how *you* conceptualize the model, since you are the one doing the modeling. "Why should BrakeSystem exist outside of Bike?" - if, because of the nature of the programming problem you are trying to solve, your program needs them to have an independent existence, they can (say, you might want to have different models that you can fit on different bikes). So, again, it's contrieved, don't overthink it. – Filip Milovanović Nov 24 '19 at 11:33
  • @LeeMerlas: What you can do here is to try and interpret, to the extent possible, what the person who gave you this task had in mind (based on any lectures and reading material they've provided, etc.), and then try to create a model that's in accordance with that; if you can't find certain guidelines that way, you may have to make some decisions on your own - just be ready to justify/defend them when asked (it could be a great way to show your understanding). – Filip Milovanović Nov 24 '19 at 11:34
  • @LeeMerlas: And if they don't see it that way and you loose points for that, well, (1) they don't know what they are doing, and (2) you shouldn't care anyway - getting a perfect score here is of no importance in any appreciable way in the grand scheme of things. – Filip Milovanović Nov 24 '19 at 11:35
  • @FilipMilovanović Thanks for the advice! I'll be sure to keep this in mind during design – Lee Merlas Nov 24 '19 at 12:19
1

There's already a nice answer but I think some more thoughts deserver to be considered:

  • I agree with Ozan: your model should have relevant level of details. If for example you'd create an application for selling bikes, you'd probably have a very flat structure of an article with a price.

  • But if you need a digital twin for example to simulate a bike, to enhance the bike with sensors and actuators, or to create a bike configurator, it's completely ok to have a model that is close to the real-world.

Not knowing your modeling intent:

  • The guiding principle for the model should be the abstraction of components. The result will be a bike and its three specific subsystems. This leaves more freedom: there are for example bikes whose brake is activated by pulling the pedal backwards without the lever.

  • Subsystems could be decomposed further, either specifically as you did, or using a more general composite pattern, where the number and type of components could vary at runtime.

Finally, the UML class diagram is only there to show the structure of the object. How the "connections will be used" is already behavior and would be modelled with behevioral diagrams such as sequence or communication diagrams.

Christophe
  • 74,672
  • 10
  • 115
  • 187
  • 1
    Yes it's actually sort of a digital twin. I'm trying to simulate a bike via a class diagram, as I've shown in the diagram above. – Lee Merlas Nov 24 '19 at 10:57