6

Step Away from the IDE! Designing with Patterns Before You Code

The main focus of this book is to learn the most popular and widely used Gang of Four (GoF) patterns. The secondary focus of this book is to consider using those patterns with real-world applications, with realistic and changing business requirements. Too many books on complicated topics such as patterns are full of abstract, contrived, or trivial examples. You have learned some popular patterns, but they do not benefit from your coding if you can’t apply them. Over the years, I’ve developed a process that works for me, and I hope it works for you too. My process eases you into patterns one step at a time as you consider a new design.

This might be a disturbing revelation, but this chapter will not present any code samples. We’ll be following the practice of diagramming our code before we start writing it.

We’ll cover the following topics in this chapter:

  • We’ll watch as the new software architect for Bumble Bikes creates a UML design for the new project using a two-pass method.
  • The new architect will make the first pass by diagramming the classes and basic structures for the project.
  • The architect will then make a second pass, wherein they will identify the appropriate patterns and update the diagram as needed.

Our story of the two sisters continues in this chapter. A huge change in the business requirements at Bumble Bikes is about to occur. We’ll see how to adapt to and overcome the inherent obstacles presented by these changes using patterns.

Technical requirements

Since this chapter contains diagrams rather than code, my usual spiel about integrated development environments (IDEs) doesn’t apply. This time, we need a different set of tools. There are many tools for drawing UML diagrams. In the real world, a diagramming exercise often happens on a whiteboard. At several points throughout this chapter, I stop and challenge you to a diagramming exercise.

If you’d like to take up the gauntlet, you’ll need some way to create and work with UML diagrams. If you’ve never drawn a UML class diagram before, there is a brief tutorial in Appendix 2 of this book. A whiteboard is fine for ephemeral drawings, but for this book, my diagrams need to be a bit more permanent, so here’s what I’m using:

  • A computer running the Windows operating system. I’m using Windows 10. Honestly, this doesn’t matter since diagramming tools are plentiful for all operating systems, and there are many that work in your browser.
  • A diagramming tool. I’m using Microsoft Visio. There are quite a few UML tools on the market. Here is a short list of tools I’ve used over the years:
  • Microsoft Visio
  • StarUML
  • Altova UModel
  • Dia
  • Umbrello
  • UMLet
  • OmniGraffle (Mac only)

You can find the completed project files for this chapter on GitHub at https://github.com/Kpackt/Real-World-Implementation-of-C-Design-Patterns/tree/main/chapter-6.

As our story continues, we see a curve ball that threatens to unravel all the work the sisters have accomplished. In the real world, business requirements change all the time. Sometimes they are small changes and they do not really affect the project. Other times, the changes are radical. The sisters are about to face a personal crisis. How should they respond? Should they take the quick and easy path and throw some stovepipe patches in place? I think by now, we’ve learned that patches lead to a big ball of mud on a large plate of spaghetti! However, if we use a disciplined and considerate approach, we might be able to avoid that kind of devolution.

Let’s see what happens.

A bad day at the agency

Tom’s phone rang at 3:58 on a Friday afternoon at his agency. The phone was on his desk, and he had been talking with his colleagues in another cubicle. Their development team had been working on a software project for a client. The first few releases had gone off without a hitch, and the customers were delighted. The customers were so happy that they even sent over a boatload of new feature requests and signed a contract extension. It was shortly after the contract extension that things started to turn ugly. Tom’s development team was way behind schedule. Implementing the last round of feature requests had left their client’s product unstable and it was crashing often. Tom was currently in a code review meeting. The group had concluded the project’s code was in dire trouble. Their management, in an effort to steal a quick win and impress their new client, had ordered the team to ship the first prototype. The next few releases came quickly. The client’s impression of the agency was that they were staffed entirely by miracle workers. However, beneath that façade (not the pattern this time), they were having trouble finding a way to extend and fix the code without a full rewrite. They found they had created a big ball of mud.

It took Tom a minute to maneuver his wheelchair around the cubicle to get back to his desk and answer the ringing phone. It was his boss’ boss, Stephanie. “That’s odd. She never calls me,” Tom thought. “Also, isn’t she on vacation in Antigua?” She wasn’t supposed to come back until next week.

Puzzled, Tom answered his phone and Stephanie started right in with her thick accent. “Tahm! We need to tawk.” It was a short conversation. It ended abruptly, along with Tom’s employment with the agency. He’d been fired. He was in shock. Everything had been going so well until, suddenly, it wasn’t. Stephanie was notoriously mercurial and often punished her employees at the slightest hint of any dissatisfaction from her coven of supervisors. She was on the fast track to the top and she wasn’t about to let a bunch of nerds derail her trajectory.

Tom remembered one time, on a different project, he had devised a method to save time and money on production by automating a difficult and error-prone process. It worked. The project went through quality assurance (QA) and all the way to production. The customers had no complaints with the release and Tom’s new methods would save a lot of time on future projects, thus making those projects more profitable. Stephanie hadn’t shown interest in any of Tom’s work until she heard about his process changes while eating at one of the management team’s power lunches. Stephanie was livid. She hated the changes so much that she berated Tom and made him do the whole project over again. She pulled the release from production and, in front of the company owners, blamed Tom for the release being late.

Tom had hoped the success of the current project had placed him back in management’s good graces. Apparently, it had not. Tom sat there stupefied for a few minutes, and then he heard Travis’ phone ring. Travis, a hot-shot C# developer, had the cube next to Tom’s. Travis disliked Stephanie so much he had assigned a ring tone to her number on his phone. It was the chorus to the song Evil Woman, by the band Electric Light Orchestra (ELO). When he heard the song’s signature guitar riff, he knew what was happening. It wasn’t just Tom being let go—it was the whole team. One after another, the phones rang, and after a short, demoralizing one-sided conversation, a heavy awkwardness settled like a thick fog.

Suddenly, the team’s bullpen area was inundated with the agency’s security team who were demanding that the developers box their personal effects. The developers were ordered not to touch a computer, not even a keyboard. Travis helped Tom with his boxes as he loaded them into the back of Tom’s specially configured Toyota Sienna. Tom had gotten the van tricked out with special equipment that allowed him to drive, something his doctors had told him he would never be able to do on his own. The steering mechanism was his own design. Tom wondered how he would continue making the payments on the van now that he was unemployed.

For the next few days, Tom looked around on all the job boards, hoping to find a new job. His disability made this difficult. He was confined to a wheelchair and had limited use of his hands. Tom typed his code with his feet using a special keyboard. It was mounted on a platform to his wheelchair, just below his ankles. Tom also had a speech impediment that made him difficult to understand. Travis and his other colleagues had adapted to his voice, so for them, it was no problem. They understood him as if there were nothing wrong. Tom was realizing that wherever he went, he was going to have to start over and it wasn’t going to be easy. As Tom mulled this over, he realized he was late for his volunteer shift. Once a month, Tom visited patients at a Dallas hospital who had recently suffered injuries that left them unable to walk. He helped them adjust and showed them very practical tips for getting around in a wheelchair. Tom smiled. Maybe he could put in more time with his charity work while he looked for a new job.

Bumble Bikes factory – Dallas, Texas

It was midnight on a dark and stormy night. Phoebe was wide awake. While she had slept during the day, her sister, Kitty, finished the code for Phoebe’s revolutionary bicycle computer. Phoebe felt a mixture of jealousy and pride as she eyed the results of her sister’s successful implementation of the Strategy pattern. Now it was Kitty’s turn to crash. She stretched out on the breakroom couch at Bumble Bikes. Phoebe’s phone rang. It was her mother. It wasn’t unusual for her mother to call late at night. Phoebe picked up the phone and her expression stiffened. “KITTY, WAKE UP! DADDY IS IN THE HOSPITAL!” she shouted to her sister.

Kitty, half asleep, let her sister drive the Jeep to the hospital. She hadn’t realized the vehicle was capable of such speed. Kitty was wide awake from white-knuckled terror by the time they completed the short trip up Interstate Highway 75 to the hospital.

They found their mother, Karina, outside the hospital room. “The doctor is with him now,” she explained. “What happened?” Phoebe asked. The girls could hear the fear in their mother’s voice. Their father was strong. He rarely got sick, and he never complained about the common aches and pains everyone gets from time to time. None of the three women had considered the possibility they would ever need to take him to the hospital.

“He’s been tired for the last few days. This last weekend, he took one of your new road bikes to ride in the Cow Creek Classic,” Karina explained. The girls knew this was a bicycle rally for charities supported by the local Rotary Club in a nearby small town. “He’s also been complaining about a rash on the top of his head. We thought it was an infected tick bite or something. This morning when he woke up, he couldn’t lift his head off his pillow. He couldn’t sit up, and he was in tremendous pain. He just started crying and couldn’t stop. I called an ambulance, and they brought us here.”

Several hours passed. Various doctors and nurses entered the room and left. Some brought equipment, while some left the room with vials of blood. Finally, the attending physician came out of the room. He was tall, slender, and spoke with a thick Eastern European accent, He was wearing a black leather jacket where one might expect a lab coat. Phoebe couldn’t help but think he reminded her of every Bond villain she’d ever seen in a movie. When he spoke to Karina, his English was fast and muddy, but his words were precise in their effect. “Your husband has dermatomyositis. It’s a rare autoimmune disease usually caused by a virus. We’ll need a surgeon to biopsy his legs to confirm my diagnosis.” Kitty asked, “What does that mean?”

The doctor went on to explain that the symptoms of the disease begin with a virus. “The body produces an immune response tailored to attack the virus. Once the virus is gone, however, the immune response mistakes healthy tissue for the infection and destroys it. In the case of dermatomyositis, the disease attacks the capillaries, which are small hair-like blood vessels. Every time you take a breath, your lungs add oxygen to your blood. This blood is carried through the arteries along with nutrients to the rest of your body, including your muscles. Your muscles use the oxygen and the nutrients, then expel waste materials that are taken by your veins back through your liver and kidneys. There the waste from the cells is filtered out and blood goes back to the heart, then to your lungs where the process starts over. Dermatomyositis attacks the tiny capillary blood vessels, which cuts off your muscles from the rest of your circulatory system. Basically, your muscles begin to die. When that happens, the body initiates an inflammatory response, which causes a great deal of pain. That’s why your father couldn’t stop crying.” The doctor continued. “Think about your worst sore muscle pain. We can measure that in your blood by testing for a chemical called creatine kinase (CK). A day or two after your hard workout, it would be normal to see your CK levels at 150 units. If you were a Dallas Cowboys football player at training camp, they might go as high as 300 units. Your father’s CK level is at 10,000 units. We’ve put him on steroids and painkillers to make him comfortable.”

What is the treatment?” Phoebe asked. The doctor answered grimly: “Dermatomyositis has no cure. We can try chemotherapy to reduce the immune response that’s hurting him and destroying his muscles.” Kitty’s face dropped and she almost started to cry. This was the problem with having a mind that is always two steps ahead. “What happens if it reaches his heart or the muscles that he uses to breathe?” she asked. The doctor’s expression was stolid. “The disease won’t affect his heart since it’s made from a different kind of muscle tissue. But his diaphragm is a concern. It will take quite a while before that begins to happen. Let’s run some tests and try some treatments to slow down muscle degeneration. We need to stall the disease for time. It is always possible the disease will go into remission,” the doctor replied.

You said there isn’t a cure!” Phoebe said angrily. She wasn’t mad at the doctor. She was mad because she wasn’t used to feeling helpless. “There isn’t,” the doctor said. “But sometimes the disease just stops and becomes dormant. He’ll have it forever, but if his body can find balance, his muscles might return to normal. I don’t want to give you any false hopes. This disease is extremely rare, and all patients react to the treatment differently. Your father’s case is extremely aggressive. Yesterday he could walk. Today, he can’t. He may never recover, or he may be totally fine next year. There is no way to tell. For now, we have to get those CK levels under control and stop the damage to your father’s muscles.” The doctor put a professional but comforting hand on Karina’s arm and strode off, disappearing into the throngs of lab coats and scrubs that filled the hallway despite the late hour.

The next month was tough for the whole family. There were constant trips for chemotherapy, physical therapy, and endless rounds of tests. As the disease progressed, the girls’ father lost the ability to speak, and one day, he could no longer swallow. The doctors implanted a rubber feeding tube in the wall of his stomach, and the strange new life continued. The four always held on to the doctor’s idea of remission. It could happen any day or never. They all chose to hold on to any day.

Their mother, Karina, fought with the medical insurance company for weeks. They had denied all their father’s medical claims because dermatomyositis is so rare there is no prescribed treatment for it from the United States Food and Drug Administration That meant all lifesaving treatments the doctor tried were denied because the treatments were classified as experimental.

Another insurance battle was over a wheelchair. Clearly, their father, who had very little use of his arms and legs, needed an electric chair, but they didn’t have the $10,000 to purchase the one his physical therapy team had recommended. After months of hospital and outpatient treatments, the family was roughly 1 million dollars in debt, having wiped out all their savings, stocks, and retirement accounts. This made buying a chair on credit impossible. Their father was a proud man and refused to let the girls sell Bumble Bikes to cover his illness. In fact, the profits from Bumble Bikes were keeping the family afloat. After their mother went through several rows with the insurance company, Phoebe got that look on her face like the one she had when she was sitting upside down at the factory in front of the TV. Something was about to happen. Something radical.

The door to Phoebe’s lab was locked for the next 3 days. Not even pizza boxes or fizzy water came in or out. Strange shadows danced in the eerie glow of half a dozen organic light-emitting diode monitors connected to Phoebe’s computer, which was visible beneath the crack under her door. On the third day, she emerged like an angel rolling away a great stone. Tucked under her left arm was a rolled tube of large format printing. It looked like blueprints for something. Phoebe called everyone in the factory together for a big meeting. The factory in Alpine joined via Zoom. Intrigued, Kitty took her usual spot at the head of the table in the conference room. Over the next hour, Phoebe revealed her plan. Bumble Bikes would now be manufacturing wheelchairs! Kitty was excited, but there was one big problem she brought up after the meeting. The two of them were already stretched thin running the bicycle business and tending to their father. The factories had to stay open to pay the mortgage. They would need help. They needed someone who knew software coding and architecture, preferably someone with experience working with disabled people, who were their target customers. They wanted someone for whom their new mission could become personal.

A physical rehabilitation clinic – Dallas, Texas

You have to use the bed to bounce yourself onto your chair,” said Tom. His speech was muddy and loud, but his new patient understood. The patient had been diagnosed with some disease Tom had never heard of before: “Dermato something something.” He was trying to teach the patient how to get out of bed and into a wheelchair. The new patient didn’t have the muscle strength to stand up and sit down, therefore he couldn’t maneuver from bed to chair easily. His doctors were considering letting him go home once he could master movement from the bed to the chair; the alternative was being sent to a nursing home.

The patient was determined not to go to the nursing home, and what he lacked in fine motor control, he could make up in large movements. Tom had the idea to have the patient propel his body upward, and when he came back down, the springs in the bed would bounce him up just high enough to trampoline him into his wheelchair. The patient threw himself up with everything he had in him. He bounced. He missed and, lacking the ability to catch himself, landed with a hard thud on the cold tile floor. Tom didn’t help him back up. The patient knew he had to learn to do this for himself. It was hard to watch but necessary.

Help him up NOW!” a woman yelled from the doorway. Tom was startled at both the loud noise and the unusual sight of two stunningly beautiful women purposefully moving toward the patient. Clearly, logistics had not been a consideration when Phoebe barked the command. It wasn’t as though Tom could just scoop up a 200-pound man and put him back in his chair. “No, don’t!” the girls’ father said weakly. He understood. He had to fight his way up into the chair even if it took a minute or several hours. “Wait outside,” their father said. It was understood by all, including Tom, that they were dismissed.

The small group waited outside the hospital room and introductions were made. The girls had come to tell their father about their plans to make him, and everyone else that needed one, a quality wheelchair, even if they were unable to pay. Bumble Bikes had become a charity overnight. As Tom listened to the plans, his face changed and his body stiffened. He had not known it, but when he left home that morning, it was going to be the first day of his new job. He had always dreamed of working as a software architect at a hot start-up. He knew his experience designing new software projects using patterns from the onset was going to be valuable. He had found his dream job.

Designing with patterns

Back at the Dallas factory, Kitty and Phoebe spent several days taking Tom through all the ins and outs of Bumble Bikes. He got an intimate tour of the factory (the physical one, not the pattern) and learned everything about its operations and capabilities. He also studied the advanced robotics systems designed and implemented by Phoebe and Kitty. It would be his job to design a similar system to manufacture the best wheelchairs anyone had ever seen.

Tom worked with Phoebe on the wheelchair designs. The designs were for three different models. The first, the flagship model, was Phoebe’s idea for the ultimate power chair. It was called the Texas Tank and it would be comfortable and capable. The chair would be able to take its owner anywhere by using track designs similar to those on a tank or bulldozer. Stairs, offroad terrain, and even ice would not be a problem. You can see the computer-aided design (CAD) design here:

Figure 6.1: The Texas Tank would be the ultimate design for a powered wheelchair

Figure 6.1: The Texas Tank would be the ultimate design for a powered wheelchair

Tom came up with a second idea. He planned to build a chair for people who couldn’t use their legs but were otherwise very strong. He planned for something light and fast that might be used for competitive sports, such as basketball. Phoebe, with this goal in mind, devised a wheelchair with cambered wheels and shorter lower-back support to allow a greater range of motion. She called it the Maverick, which is a cowboy who plays by his own rules. You can see this design here:

Figure 6.2: The Maverick

Figure 6.2: The Maverick

The last model is what Phoebe bemusingly called the Plano Wheelchair. “It’s, you know, just a plain ol’ wheelchair,” Phoebe said. So far, all of Bumble Bikes’ products were named after something related to Texas. The city of Plano, Texas, lent its name to the pun. It’s light, compact, and functional, and it gets you where you need to be. “Maybe it’s used temporarily, or with some upgrades to the seat, maybe you use it forever,” Phoebe explained. You can see the design for the Plano Wheelchair here:

Figure 6.3: The Plano Wheelchair, because it’s just a plain ol’ wheelchair

Figure 6.3: The Plano Wheelchair, because it’s just a plain ol’ wheelchair

Phoebe and Tom showed their designs to Kitty. She loved them. Phoebe stated, “When we made the bicycle factories, and the software, we built everything as we went along. We didn’t really know what we were doing. We learned patterns as they were needed. We’re kind of hoping we could leverage our experience along with yours to get this done a little faster than last time.”

“And hopefully with fewer mistakes,” Kitty chimed in. Phoebe rolled her eyes. “It all works, doesn’t it?” Phoebe shot back.

Indeed, it did. It wasn’t perfect, but everyone working at Bumble Bikes had learned that “perfect” is the enemy of done. You can’t wait for your software to be perfect. No bicycle would ever be built that couldn’t be improved. Whether it’s software, bicycles, or anything else, designing and coding don’t bring in money, which is the main goal for most companies. These activities are necessary, but only shipping products based on design and code turns a profit. If you code or design for too long, your company goes bankrupt.

“I need to diagram everything in UML before I start coding,” said Tom. Every day the sisters spent with Tom made it easier to understand his stammering speech. Phoebe just stared at him for a minute. Only Kitty understood the nonverbal “Who does that?” expression on her face. Tom explained designing with UML before opening the IDE will help the project move faster. You’ll see your design mistakes sooner, and it is usually easier to refactor a diagram than it is code. Your diagrams are also where you’ll identify patterns in advance, rather than reactively when you are trying to refactor something already in production. Besides, it is impossible to succumb to the real-world temptation to clean up and ship a diagram. Effectively, you should be able to replace throw-away code with a set of diagrams.

It was important for the sisters to learn to trust this qualified outsider. It was his project, and the girls knew the value of not micro-managing Tom. Phoebe suited up a laptop for Tom with the finest tools money can buy, a condition Tom insisted on as part of his employment. Kitty and Phoebe acquiesced to this condition without a second thought. They showed him to his own lab, which the girls had hastily, but competently, fashioned from studs, insulation, and drywall in a back corner of their Dallas warehouse. They painted the room, and as an office-warming gift bought Tom a bonsai tree from a pop-up vendor stationed on a nearby street corner. The office was furnished using some of the extra furniture and equipment Phoebe had been hoarding in her own lab. “First rule of working in IT…,” she said, “Never give ANYTHING back!” This was humorous, given she was half owner of the company and in charge of IT. Humorous, but true.

The first pass

The low-hanging fruit in any object-design exercise is deciding on the basic structures for the objects. Tom knew this was likely the place he would use Creational patterns, though he didn’t concern himself too much with which ones he would use. Experience had taught him that analysis-paralysis is a real problem when a developer starts using patterns. You can stare at a blank whiteboard all day trying to decide whether to use an Abstract Factory or a Factory Method. Maybe both together somehow? Maybe we can fit a Command or Singleton in there too?

Tom began by drawing the classes and not worrying about patterns at all. Patterns usually emerge out of chaos, so don’t be afraid to create chaos first. Since we’re just diagramming, there is no way the pointy-haired boss can tell you to “Clean it up and ship it Monday.” Tom’s new bosses would never give him that command. Neither Phoebe nor Kitty had pointy hair, nor were they likely to mistake an Etch A Sketch for a quality tablet computer; this is the subject of an inside joke the girls had shared while working with the IT executives at MegaBike Corp two summers ago.

Tom reasoned that wheelchairs are like bicycles, but not so similar that there would be any reuse in the base classes. That said, the project could be structured in a similar way. Tom set to work creating a set of interfaces and classes that would represent Bumble Bikes’ new line of powered and unpowered wheelchairs.

I’d like you to stop reading and see whether you can create a UML diagram that describes powered and unpowered chairs as they were described by Tom and Phoebe. When you have finished your diagram, see how closely your work matches Tom’s.

Tom started by diagramming the Wheelchair class, like so:

Figure 6.4: Tom’s initial Wheelchair class

Figure 6.4: Tom’s initial Wheelchair class

At first, the Wheelchair class had everything on it. But as he considered further, he decided to split the chairs into two families: powered and unpowered. See following diagram:

Figure 6.5: Tom split the design into two main types of wheelchairs

Figure 6.5: Tom split the design into two main types of wheelchairs

He considered which properties these families would have in common, such as ModelName, Year, and SerialNumber. He hoisted these definitions into an interface and an abstract base class. He could probably get by with one or the other, but since his entire design would be structured around this diagram, he decided being inclusive was the way to go.

The unpowered chairs were straightforward with regular wheels and casters. The Texas Tank, on the other hand, was an entirely novel design that used tracks instead of wheels. The powered chair would also need a power source, a motor, and a steering system. These could be diagrammed separately, but Tom realized that since the track designs on the powered chair were so strange, it might behoove him to design around this fact. He made an abstract PoweredChair class that encapsulated the other 99.9% of the powered chairs on the market. It wasn’t inconceivable that he might one day be asked to represent such a chair in his code.

The whole diagram wound up looking like this:

Figure 6.6: Tom’s initial design

Figure 6.6: Tom’s initial design

Let’s look at it by the numbers, as follows:

  1. Tom decided an interface at the top of this structure made sense because, in the future, we need to be able to pass around wheelchair-like objects. This is an attempt at future-proofing. This kind of design strategy usually works, but really, there is no such thing as future-proof.
  2. An abstract implementation of the interface is needed when there’s some shared method implemented across subclasses. We have something like that in the Bicycle class with the Build() method, as shown here:
Figure 6.7: The Bicycle Factory method pattern implementation from Chapter3.

Figure 6.7: The Bicycle Factory method pattern implementation from Chapter3.

  1. As with the Bicycle class, this class has two computed properties: Year and SerialNumber. These act like methods. At this stage, we can justify the extra abstract class in the name of being DRY. For an explanation of don’t repeat yourself (DRY), please refer back to Chapter 2, Prepping For Practical Real-World Applications of Patterns in C#.
  2. The UnpoweredChair class inherits from Wheelchair. Tom knows the left and right wheels on a wheelchair may look identical. In this first drawing (Figure 6.4), he had all the wheels in an array. Wheels on a wheelchair are not identical, and Tom understands he needs to not think so concretely. He isn’t modeling wheels as part of the chair. He’s modeling slots for wheels that should on some level be interchangeable. Most wheelchairs have two big wheels as the main support, and a set of smaller wheels, or casters, to balance the craft overall.
  3. The PoweredChair class also inherits from Wheelchair. It is modeled to represent the most common powered chairs on the market. Since Tom has ridden around in one for the entire duration of his 36-year life, he knows the design very well. His class here inherits common properties—some computed—from the base class. The elements unique to the powered chairs, in general, are represented. Every powered chair, including the Texas Tank, will need a power supply, steering, and a motor. Again, this is an attempt at future-proofing. It is easy to predict that one day, Bumble Bikes will make a more common design for a powered chair. While the Texas Tank is amazing, Phoebe designed it as something she knew her father would love if remission never becomes a reality. The Texas Tank is not for everyone. It is heavy, expensive, and will smell like heavy machinery. Note that Tom has considered there will need to be methods in the design, but in this pass, he hasn’t committed anything to the diagram. He continues to work on the obvious needs as quickly as he can to keep the momentum.
  4. Two classes inherit from the UnpoweredChair class. I think these speak for themselves. The only difference between the two is the cambered wheels on SportChair. In an actual chair, the wheels tilt outward for improved speed and agility. If you didn’t notice this detail, refer back to Figure 6.1 and you can see the camber on the wheels.

Tom is happy with his morning’s work. Kitty and Phoebe order lunch from their favorite Mexican restaurant and the three relax. After lunch, Tom is feeling energized and goes to work on the next round of revisions.

Once you get your base classes diagrammed, the next step is usually to think about composition. We have properties and fields in our objects. What information will go inside those properties and fields? When we were beginner coders and things were simpler, it was a combination of primitives. We didn’t need composition, but now we are worldly and wise, and Tom is no exception. He needs to hash out the structures that make up the base classes via composition. For example, what should we do with the Seat property in the Wheelchair base class? The various chair designs have different seats; therefore, it makes sense to create an interface for maximum flexibility, and then document that requirement in the diagram. Tom is taking a different attitude and approach by diagramming and planning. This is different from the attitude that Phoebe and Kitty had taken while building Bumble Bikes. They skipped any sort of diagramming or planning effort and went directly to writing code. Just look at all the parts where Tom is guessing or making judgment calls. The Inflate() and Deflate() methods are a great example. He’s not sure whether they will be needed or not. The exercise of abstracting a real-world object into class code is mainly about modeling what is important to the application. A Person class in an address book app on your phone needs a different level of detail compared to a Person class in a medical records application. While you are diagramming, you needn’t worry about being DRY, YAGNI (which stands for you aren’t gonna need it), or violating SOLID (if you don’t know what these acronyms are, please refer to Chapter 2). At this stage of designing your class structure, it is only a diagram. The whole point of diagramming is to get the design in a format that can be discussed, argued over, pondered, socialized, and changed. Sure, you’re thinking about SOLID or YAGNI, but it’s okay to not be perfect at the point of conception. The diagram will naturally evolve, and you will make mistakes and have oversights that you can correct and refine. Once the diagram becomes code, all those pesky rules will begin to apply. The code is real. There are rules, and make no mistake about it, if you work on a team, you will be judged by those rules.

Tom diagrams all the components he foresees, including these:

  1. The seat
  2. The frame
  3. Wheels and casters
  4. The motor for the powered chair
  5. The steering mechanism for the powered chair
  6. The battery for the powered chair
  7. The track drive system for the Texas Tank

Let’s watch Tom diagram each set of classes. Each set is going to consist of an abstract class or interface, and appropriate concrete classes inheriting from that abstract class. Don’t forget—in UML, the title of an abstract class is written in italics.

The seat

The seat is probably the most important part of a wheelchair. Tom knows this first-hand—each chair will need a different kind of seat. Bumble Bikes can get away with the less expensive generic seating on wheelchairs that are not meant to be sat in all day. The Plano Wheelchair is the perfect example of a transporter chair. A basic wheelchair, like the Plano, is used for brief transport from one location to another. The chair’s user, for example, will transfer from the wheelchair to an office chair or bed. When the need arises to move from one spot to another, the user will transfer back to the transporter chair and set out to the new location. The basic wheelchair does not have a motor. This differs from the other wheelchairs.

The Maverick wheelchair too has a special-purpose chair. This chair is designed to be light and maneuverable. Similar to the Plano Wheelchair, it isn’t designed to be an all-day seat. The Maverick wheelchair is not motorized.

The powered chairs, however, cater to different kinds of users. The largest group of users consists of aging senior citizens. This group is not disabled. They can stand and walk short distances but require a chair for longer-distance walking. The second group of wheelchair users are like Tom. They are quadriplegics and have little-to-zero mobility in their arms and legs. These wheelchair users generally lack the ability to transfer on their own. Therefore, they do not need a cheap seat because they are in the chair for long stretches of time. They require a comfortable chair. This group, Tom and Phoebe decided, would be the design inspiration for the Texas Tank, the ultimate powered wheelchair.

Tom drafts a design for the seat classes. His ideas are reflected here:

Figure 6.8: Tom’s design for the WheelchairSeat class

Figure 6.8: Tom’s design for the WheelchairSeat class

This design is simple. It consists of an abstract class called WheelchairSeat. The properties are straightforward. Tom positioned the concrete classes with the unpowered chair seats on the left side of the diagram and the powered chair seat on the right. Later, when we combine our designs into a larger diagram, you can expect this convention to be used.

The frame

Our three wheelchairs require three very different frame designs. The Plano Wheelchair is simple, reasonably light, and a very common design. The Maverick wheelchair needs to be very light, but tough enough to weather collisions and crashes, which are inevitable during passionate competition. The Texas Tank needs to be, well, a tank. It has heavy tracks, a large battery, and an oversized chair for a seat.

Tom gives this some thought and decides to keep this simple for now. He could try to get down in the weeds and figure out how to represent all the extruded aluminum tubes, bolts, joints, and hinges that make up the chair frame. However, Tom isn’t that kind of engineer, so he decides to include a field to hold the file path to the CAD file for the frame. Kitty and Phoebe agree with Tom. You can review Tom’s design in Figure 6.9. The diagram shows a simple abstract class representing a wheelchair frame. As before, the unpowered components are on the left, while the powered class is drawn to the right:

Figure 6.9: Tom’s design for classes representing the frames of the wheelchairs

Figure 6.9: Tom’s design for classes representing the frames of the wheelchairs

Wheels and casters

You can’t really have a wheelchair without wheels, can you? The Plano Wheelchair and the Maverick wheelchair will use traditional spoked wheels, similar to those used in bicycles. Standard designs for wheelchairs involve two large fixed wheels and a set of smaller wheels configured as casters. The casters can turn in any direction.

In Figure 6.10, Tom calls his abstract class MechanicalWheel. This class can represent the wheels and casters, but it cannot represent the tank-style treads on the Texas Tank. The following diagram shows the design for the MechanicalWheel class along with the two-wheel subclasses. The WheelchairWheel class represents the larger wheels on the sides of the chair, while the Caster class represents smaller wheels on a wheelchair that can rotate, providing maneuverability:

Figure 6.10: The MechanicalWheel abstract class and its subclasses

Figure 6.10: The MechanicalWheel abstract class and its subclasses

Tom has modeled everything he needs for an unpowered chair. They are simple machines. The real design challenge, and certainly the most rewarding, lies in creating a class design for the powered chair. Tom is careful to not specifically model the Texas Tank. The Tank is a very ambitious project—the kind that can easily be canceled because it’s going to be expensive to build. Furthermore, the Tank’s unconventional design might not appeal to a wide audience. Only time and a few marketing studies can tell. Tom’s strategy then should be to create component classes that are not specifically tied to the Tank design, but rather to more common powered chairs. Tom decides to start with the motor.

The motor for the powered chair

Tom’s powered chair is still running with its original motor. He bought the chair over ten years ago. These motors are common and Tom is intimately familiar with them. The motor for a powered wheelchair operates off direct current from a battery. The motors are required to have high torque with a relatively show speed, and they need to last a long time. Modeling a such a motor is not a problem. Tom’s design is shown in Figure 6.11.

Figure 6.11: The motor class diagram for powered chairs

Figure 6.11: The motor class diagram for powered chairs

Since electric motors are common and generic, Tom decides to make them an abstract class. He adds a few properties and a method to simulate the motor being switched on and off. Then, he adds a subclass to handle the specifics of an electric motor used to power a powered chair.

The steering mechanism for the powered chair

Tom’s chair uses a joystick mounted to the left arm of his chair to control it. The joystick is sensitive to how hard it is pushed in any given direction. The harder you push the stick, the faster the chair moves. Tom sees no particular reason to redesign this nearly ubiquitous system. His class design can be seen here:

Figure 6.12: The steering mechanism for the powered chair design

Figure 6.12: The steering mechanism for the powered chair design

The properties Tom chose for the steering mechanism represent a wide range of industrial joystick control systems, used in everything from drone flight controls to automation to—you guessed it: powered wheelchairs.

The battery for the powered chair

The motor for the wheelchair is electric, and we need a battery to power the system. Any industrial-grade battery with the right voltage and current should work. We want a battery that lasts a long time. We need a battery with a high enough ampere (amp)-hour rating, but not so high that the weight of the battery affects the operation of the chair. Phoebe will definitely want to experiment with different batteries. As you can see in the following diagram, Tom created a base class that might describe any battery and left the implementation details for later on in his WheelchairBattery subclass:

Figure 6.13: A class diagram representing a battery system for the powered wheelchair

Figure 6.13: A class diagram representing a battery system for the powered wheelchair

The track drive system for the Texas Tank

Tom was out of his element on this one because he had zero experience with track drive systems. Kitty and Phoebe, having spent time at the family cattle ranch when they were young, had a tacit understanding of how track drive systems worked. The three teamed up and sourced a few vendors that might supply their requirements. Since Tom was pressed for time, he simply looked at the properties used to describe the track drive systems on the vendors’ websites. From these sources, Tom derived the set of properties you’ll see in the following diagram:

Figure 6.14: The track drive system

Figure 6.14: The track drive system

Tom was sure that of all the components he modeled, the track drive system would be the one to change and evolve. This is the one where Phoebe would be working on many prototypes as she built them. He called his subclass HighDriveTrackSystem because this is what the design is called. In the following diagram, you’ll see our Texas Tank design with a high-drive system. The track is triangular with a large wheel situated high in the track design. Compare this in Figure 6.15 with a standard continuous track design on a bulldozer, and you’ll see the difference:

Figure 6.15: A continuous track drive system on a bulldozer compared with the high-drive design on our powered chair

Figure 6.15: A continuous track drive system on a bulldozer compared with the high-drive design on our powered chair

Phoebe and Kitty designed the chair using the high-drive system because it provides a more absorbent suspension. High-drive systems are also less prone to wear and fail because they isolate the drive sprocket to a flexible section of the track drive. “She’ll handle like a dream!” Phoebe exclaimed with a broad, toothy grin. The engineering prototype didn’t take long to build. The hard part was getting Tom off the Tank, as we can see here:

Figure 6.16: Tom monopolized the Texas Tank prototype

Figure 6.16: Tom monopolized the Texas Tank prototype

Eventually, the Tank’s battery was depleted, at which point, Tom got back to work.

Adding patterns

Tom feels pretty good about his first pass. He has enough to spark some serious discussion about how to structure the project. This is the objective of the first pass. Tom makes a quick list of all the patterns Kitty and Phoebe had used in the bicycle project, as follows:

  1. Creational patterns:
    1. Factory pattern
    2. Abstract Factory pattern
    3. Factory method
    4. Builder
    5. Object pool
    6. Singleton
  2. Structural patterns:
    1. Decorator
    2. Façade
    3. Composite
    4. Bridge
  3. Behavioral patterns:
    1. Command
    2. Iterator
    3. Observer
    4. Strategy

Tom begins to focus on the diagram and sets to thinking about the application of each pattern. One by one he looks for opportunities. Some of them are obvious. Some of them may not be needed. Tom’s diagram doesn’t currently include any changes to the bicycle factory’s robotics. For the most part, the robotics classes should not be tightly coupled to making bicycles. After a few hours of personal debate and much consideration, Tom is prepared to discuss patterns with Kitty and Phoebe. He is able to book time on their calendars for that evening.

See whether you can generate your own ideas on how and where creation patterns might be appropriate. Remember—it’s a diagram and this is brainstorming. It isn’t an exam with definitive right answers. It’s normal and okay to be wrong or unsure sometimes. In the next section, Tom will present his diagram containing all the patterns he intends to use for the project. If you’d like to try to figure out which ones are the most appropriate, pause here and make yourself a list. Beware of the Golden Hammer! It is not necessary, nor even desirable to try to use every pattern you know in one project.

The first design meeting

Tom configured his computer’s display to share with a large 72” OLED 8K screen in the Bumble Bikes conference room. The lights were dimmed. Phoebe, true to character, made popcorn and passed around fizzy water. With everyone seated comfortably, Tom began his presentation by discussing the base object structure. Once the girls were up to speed on the basics, Tom directed the discussion toward creation patterns. As the sisters listened to Tom, it was clear that they held him in high esteem. They appreciated his abilities and the manner in which he adapted to the life fate had dealt him. The sisters were aware that most people are very uncomfortable interacting with someone in a wheelchair, especially if they also have impaired speech. They knew Tom desired to be seen for himself, and the sisters treated Tom as they did any other colleague. The sisters snapped from their collective reverie as Tom began his presentation.

“The first pattern I want to use is straightforward. The Abstract Factory pattern is used when you want to make related families of objects. You used it when you wanted to manufacture your own parts for different types of bicycles. You have classes for bicycle frames for road and mountain bikes that are not in any way interchangeable in the real world, but their abstract structures are similar enough to follow common interfaces. We can do this same thing with wheelchairs in two places. First, we could have an Abstract Factory creating parts for the wheelchairs just like you do for the bicycles. But I wonder if we couldn’t go an extra step and use the Abstract Factory pattern to determine whether we are generating a bicycle or a wheelchair at the highest level of your factory automation system. The clients of Factory patterns don’t care about the structure of the object they’re getting from the factory. The manufacturing system, therefore, shouldn’t care whether it’s making a bicycle or a wheelchair.”

“That’s true, Tom,” said Kitty. “But I’ve found the Builder pattern to be more flexible. While Abstract Factory returns the produced object immediately, the Builder pattern allows you to attach extra steps in the build process.”

“Hey!” Tom interjected. “If we use the Builder, we can combine some of the other Creational patterns as part of the build process. You used the Composite pattern to generate a cost model. You also used the Bridge pattern to handle bicycle paint jobs. I think that would be a big deal with wheelchairs. I work with a lot of kids at the hospital, and I know they would rather have crazy colorful paint jobs on their chairs than the standard black and chrome all the other companies make. The Builder could generate a bridged object as well.”

“Couldn’t you then make the director class for your builder a singleton?” Kitty asked.

Phoebe was sitting at the end of the table eating her popcorn. She leaned back and rolled her eyes. Kitty and Tom were in full-on geek mode.

“This is going to require another pass at my design,” Tom said. He remembered the age-old phrase, “No battle plan survives first contact with the enemy.” He hardly regarded Kitty and Phoebe as his enemies, but he wasn’t expecting his preliminary design drawings to be considered final or complete. This is the first iteration. Tom said, “I need to reorganize all the components so that they’ll fit with the Composite pattern. I think that will probably change a lot of things.” It was late, so the team adjourned for the night.

The second pass

Tom was excited the next morning. He was at the lab early and went straight to work refining the diagram. All totaled, he felt he could use five of the patterns Kitty and Phoebe used in the bicycle project, as follows:

  1. Creational patterns:
    1. Builder: Tom can leverage this pattern to handle the complicated object creation needed for a wheelchair class, including handling the composite and bridge implementations
    2. Singleton: Tom considers the builder class might be made into a singleton to save resource.
  2. Structural patterns:
    1. Composite: Tom will create a cost model similar to the one created for the bicycles, but this time it will be integrated directly into the structure of the wheelchair classes instead of being created separately.
    2. Bridge: As with the bicycles, Tom uses the bridge to vary complexity in the paint jobs and the wheelchair classes independently.
  3. Behavioral patterns:
    1. Command: The Command pattern will be used to bundle all the details needed to create a wheelchair into a single object that can then be sent to a receiver class

Tom set up the second design meeting with Kitty and Phoebe, which was accepted with less fanfare. The trio huddled around the conference room display and Tom presented his diagram.

The Builder pattern

Tom wasted no time getting into the weeds. “We talked about the possibilities of using the Builder pattern. I think it’s going to work really well,” Tom said.

Deftly moving the pointer around the screen with his big toe, he added the classes needed to implement the Builder pattern. You can see the result here:

Figure 6.17: Tom has added the structures required for the Builder pattern

Figure 6.17: Tom has added the structures required for the Builder pattern

We covered the parts of the pattern in detail in Chapter 3, Getting Creative with Creational Patterns, but let’s quickly review this:

  1. The builder is defined by an interface or an abstract class. Here, that will be IWheelchairBuilder.
  2. The builder is controlled directly by a WheelchairBuilderDirector class that contains a private instance of the builder interface. All the work is done by the director.
  3. Concrete instances of builders are defined for each product. In this case, each wheelchair model gets its own builder, giving us great flexibility given the inherent differences between the models.

“This is a good start,” Kitty said. “We also talked about making the builder a singleton.”

“Right!” said Tom.

The Singleton pattern

Tom replied, “There’s not much to say about this one.” Tom made two changes to the WheelchairBuilderDirector class in the diagram. You can see the changes here:

Figure 6.18: The structure for the Builder pattern used for wheelchairs has been made into a Singleton. You can tell since there’s only a single number on the diagram

Figure 6.18: The structure for the Builder pattern used for wheelchairs has been made into a Singleton. You can tell since there’s only a single number on the diagram

“To make this builder a Singleton, I just added the internal reference WheelchairBuilderSingleton (1). This will hold an instance of WheelchairBuilderDirector if the object has already been instantiated. Then, I added the GetInstance() method. This method will check to see whether there is an instance already in WheelchairBuilderSingleton. If it’s empty, the method creates an instance, stores it in that private variable, and returns the instance. If there’s already an instance there, it returns that one. I’m not sure we get anything from making it a singleton. Usually, singletons work best in conjunction with an object pool for expensive instantiations such as database connections. I’m not sure we have that here, but we can decide when we write it. Taking it out isn’t a big deal.”

The girls nodded their heads in understanding. They were both waiting anxiously to see what Tom did with the Composite pattern, which was next on the agenda.

The Composite pattern

“I really liked the way you used the Composite pattern with your bicycle models. You were able to leverage the pattern to compute component cost and weight for shipping. But you modeled a special structure just for that purpose,” said Tom.

Kitty fielded the criticism, saying, “A separate structure met our needs at the time we built it. We already had our classes in production code and we didn’t want to violate the open-closed principle of SOLID.” We covered SOLID in Chapter 2.

Tom wanted to build a Composite pattern directly into the structure of the wheelchair. This was a little bit challenging because he didn’t necessarily want the structural requirements of the composite to define the structure of the wheelchair. Instead, what he really needed was a normal object structure that acted as a composite. “We can improve on your design by baking the composite structure directly into all our objects. We need to think about the wheelchair assembly as a hierarchy. I see it as looking like this,” Tom said. He wheeled over to a nearby whiteboard. The girls had set one up on a special stand so that Tom could reach it. He sketched out a hierarchical diagram showing how the parts of an unpowered chair might be modeled. Once he had drawn it, Kitty grabbed a marker. “That’s good, but the powered chair would look a little different,” she said while sketching out her own idea for a hierarchical powered chair model. The whiteboard looked like this:

Figure 6.19: Tom and Kitty were each able to draw a powered and unpowered wheelchair as an object hierarchy to make it compatible with the Composite pattern

Figure 6.19: Tom and Kitty were each able to draw a powered and unpowered wheelchair as an object hierarchy to make it compatible with the Composite pattern

Shifting the group’s focus back to the computer monitor, Tom continued. “With this structure in mind, we need to overhaul the classes that specify the construction of the frame. Instead of each piece being constructed and assembled as one piece, the robots would need to assemble a collection of parts in order. Structuring this way allows accounting to meticulously track the weight and cost of each wheelchair down to the smallest component. With the ability to track weight and cost, the sales department will be able to price the chairs competitively and work with insurance companies and charities to make sure the chairs can find their way into people’s lives who need them without bankrupting the company.” Kitty and Phoebe continued staring at the screen, barely blinking.

He continued, “The outsourced logistics team at ExFed can use the weight calculations to guarantee accurate shipping quotes. In the bicycle project, you constructed a separate object to house your composite structure.”

“What I’ll do for this project is hide the composite in the normal structure,” Tom said as he zoomed into the appropriate part of the diagram. He dragged a new class to the page and titled it WheelchairComponent. He then italicized it and explained why he added the members needed for his Composite pattern idea. You can see this idea here:

Figure 6.20: Tom had to add and refactor a lot of classes to have it fit the Composite pattern without necessarily looking like a composite

Figure 6.20: Tom had to add and refactor a lot of classes to have it fit the Composite pattern without necessarily looking like a composite

“What I did here was to add a WheelchairComponent abstract class. I usually do this instead of adding an interface when I need to add methods with implementations in them. In this case, we’ll have the DisplayWeight() and DisplayCost() methods, which will recursively process the subcomponents to arrive at totals for weight and cost. Then, I modeled all the components for the wheelchairs as abstract components in case we ever need to swap out concrete versions of those components.” Tom created a separate diagram to show this idea. Experience has taught Tom, who is now teaching this best practice to Kitty and Phoebe, that the best diagrams are small, focused, and concise. Instead of spreading out the classes in the diagram and appending subclasses beneath each abstract class, Tom made a diagram that just shows the inheritance chain for the seating components. You can see this diagram here:

Figure 6.21: The concrete seat objects inherit from the abstract WheelChairSeat class, which inherits from WheelchairComponent

Figure 6.21: The concrete seat objects inherit from the abstract WheelChairSeat class, which inherits from WheelchairComponent

Tom looked over at Phoebe. Clearly, the gears were turning in her mind. She finally spoke, saying, “What we’re doing here is have everything inherit from WheelchairComponent. The WheelchairSeat abstract class is there to make sure the concrete seat objects can be represented in the composite structure using Liskov substitution. Any seat will have the structure of the parent classes.”

“That’s right,” Tom said. Kitty continued her sister’s thought. “We can put any seat on a frame and still be able to have weight and price. That means as long as we assemble the hierarchy in the right order,”—she pointed back to the whiteboard (Figure 6.18) as she spoke—“we’ll be able to have the benefits of the Composite pattern and we will also have a flexible way to compose our wheelchairs.” Tom nodded in agreement. “Think of it this way: it’s like basic composition, which might be why the GoF called this the Composite pattern, but it is composition done a different way. It is just as flexible, but it is also iterable because the composition uses lists to hold the parts.”

Phoebe wrinkled her nose. “Should we worry about the fact this structure might make it possible to add 200 seats to a wheelchair?”

“No,” said Tom. “You can handle that with encapsulation logic. Each class can impose rules on the list of components it contains. Liskov substitution makes the structure flexible, which gives you the power to construct anything. But you need to temper this by added encapsulation methods that control what goes into the composition.” This time it was Kitty’s face that was scrunched up like she’d smelled something awful. “This seems very complicated for the developer that has to use this method. They’ll have to remember to assemble the object in the right order. They’ll have to look back at the diagram (Figure 6.18) anytime they want to build a wheelchair.”

“Not so,” said Tom. “Remember the Builder pattern we are using to direct the assembly of the object?” Both the girls’ faces relaxed. They instantly got it. “The patterns can be used together! The builder’s job, its raison d’être, is to handle the construction of complex objects using a well-defined set of steps.” “We’ll need to alter our builder class diagram to account for this change,” said Kitty. Phoebe looked alarmed. “Aren’t we violating the open-closed principle? We’ve already designed that class!” Kitty rolled her eyes as Tom grinned. “No, Phoebe. It’s just a diagram. It’s not production code!” At that moment, Phoebe fully understood why Tom had chosen to diagram his work before he committed it to code. At a master’s keyboard, coding becomes a discipline. We need a way to relax the rules so that we can at least have a chance at getting our design right the first time.

“The parent WheelchairComponent class has the Subcomponents list in it, but I’m thinking of hiding it. For now, it’s public, but my idea is to have the builder add the appropriate subcomponents to the array at build time. This means I can have a traversable component tree without forcing my whole structure to conform to a common interface, which is probably impossible,” said Tom.

“Hey, that’s pretty neat!” Kitty said enthusiastically. “Can we deal with the changes to the Builder pattern really quickly?” Kitty asked. The trio brought up the diagram they had created in Figure 6.16 and began to modify it. After a few minutes, it looked like this:

Figure 6.22: The Builder pattern with the addition of methods to build the composite

Figure 6.22: The Builder pattern with the addition of methods to build the composite

“That’s it?” asked Phoebe. “What about all that fancy encapsulation logic we talked about? Where is that on the diagram?” Phoebe pressed. “The logic will be the Make method in the WheelchairBuilderDirector class. Remember, it is the director class that is responsible for the logic that assembles and returns the object.”

Kitty and Phoebe seemed enthusiastic about Tom’s work. He moved on to the next pattern.

The Bridge pattern

“In our last meeting, we discussed reusing the Bridge pattern work from the bicycle project. I think having paintable frames will be popular because most companies just make black or gray wheelchairs. That’s fine for hospital loaners, but if you’re a lifer like me, after a while you’re ready to upgrade.” Tom smiled. His chair had a little bit of red paint on a few parts of the frame, but it was far from upgraded.

Phoebe said, “With our bicycles, one of our Kickstarter backers designed our first custom paint job. Maybe you should come up with one for the wheelchairs.”

Tom flushed. “I’m honored, but really, I’d rather bring in a bunch of the kids from the hospital and see about making some designs they like.” Kitty smiled warmly. Phoebe’s respect for Tom deepened.

Changing the subject, Tom once again focused on his screen. “I didn’t change anything from the bicycle project’s implementation except for adding the concrete painter classes.” Kitty and Phoebe nodded, glad that Tom was going to be able to reuse some of their earlier work. “Of course, I also added a FramePainter attribute to the abstract Wheelchair class so that all the subclasses will have it,” Tom concluded. You can see the UML diagram for the Bridge pattern applied to the wheelchair project here:

Figure 6.23: The Bridge pattern is generally unchanged save for the concrete classes

Figure 6.23: The Bridge pattern is generally unchanged save for the concrete classes

“Are the builder classes going to be directly adding the paint to the wheelchair objects?” Kitty asked. Tom said, “I’m glad you reminded me. I would have forgotten to add that to the builder diagrams.” Tom made a quick modification to the builder diagram we last saw in Figure 6.22. The new version can be seen in Figure 6.24:

Figure 6.24: Builder pattern diagram revised with the addition of the BuildFramePainter() method

Figure 6.24: Builder pattern diagram revised with the addition of the BuildFramePainter() method

Next on the list was the Command pattern.

The Command pattern

There is one last refactor I want to make. You used the Command pattern to direct the manufacturing robotics to build your bicycle. Naturally, I want to use the same manufacturing system. I think the differences can be easily handled,” Tom said.

“OK,” Phoebe said quizzically with one raised eyebrow. “What are you doing to my babies?

Tom dragged some classes to the diagram and arranged them to form the Command pattern. Once he got everything filled in, his diagram looked like this:

Figure 6.25: Tom’s change to the Command pattern is fairly minor

Figure 6.25: Tom’s change to the Command pattern is fairly minor

Tom said, “We need to make a change to the DoBusinessLogic method in AssemblyLineReceiver. You have it set up to only take one interface: the IPaintableBike interface. I can’t force-fit my wheelchair to be a paintable bike. We could change the central interface for my project from IMobilityDevice to IManufacturable.” He made the change as he was talking. Tom continued, “This way, the interface has elements common to bicycles and wheelchairs, and probably anything else you’d ever want to make.” He finished speaking as he added a new member variable to the IManufacturable interface: ManufacturingStatus. This was in the PaintableBicycle class, but to this point, Tom hadn’t thought to put it in the diagram. You can review the revisions here:

Figure 6.26: The final change renames the central interface IManufacturable.

Figure 6.26: The final change renames the central interface IManufacturable.

For the first time during the presentation, Phoebe was standing up. She stared blankly for a moment. “I don’t know about that,” she said. She didn’t say another word for the rest of the meeting.

Kitty picked up the slack. “Tom, this looks great! I can see Phoebe has some trepidation about your last refactor, but we can work through that. Let’s get started on the base classes for your project right away.” Kitty and Tom spent the rest of the afternoon setting up a repository on GitHub and configuring a continuous integration (CI) build for the new project. Having pushed a trivial class and watched it build, Tom added a simple unit test to the class. It too passed. It was about this time when the three realized it was very late at night, or very early in the morning, depending on your point of view. Though they didn’t really want to, they reluctantly broke for the evening (or morning) and resolved to get started the next day at the crack of noon.

Summary

This chapter presented a design scenario where we saw a drastic change in business requirements for our nascent bicycle company as they made the brave decision to branch out and make wheelchairs to help those in need. As usually happens with these things, this change was not planned and happened at an inopportune moment. Strapped for time and inspiration, Kitty and Phoebe hired Tom, a wheelchair-bound software engineer who found himself aggressively unemployed following an executive meltdown at his previous employer.

Tom leveraged his expertise in software development, his personal experience, and his experience as a volunteer helping recently injured patients learn to cope with living in a wheelchair. He was able to bring a fresh perspective to the problem and began to design a solution that fits the manufacturing environment as well as the very real cost and resource constraints already extant at Bumble Bikes.

After about a week of analysis and design using UML, Tom was able to plan his development effort leading up to the first release of the new wheelchair project.

Tom did a number of things differently than the girls did on the bicycle project. Mainly, he designed with patterns and UML first, instead of trying to find patterns as he went. Hopefully, this will lead to fewer instances where we need to make a drastic change to the code that might violate our sacrosanct SOLID principles. Tom was adamant that this practice would save a lot of time and frustration on the project.

Tom followed a process for developing his design diagrams as follows:

  1. In the first pass, he designed all the base classes upfront. He just drew the classes and the inheritance lines.
  2. Once he had the classes, he filled in the inheritance and composition lines.
  3. He thought about patterns, but didn’t diagram them. Instead, he held a meeting with his development team who had experience and insight with the same set of patterns he was working with. Effectively, he was using iterative development, but with a diagram instead of code. He got input from his stakeholders before trying to finish the whole design project.
  4. Tom, Phoebe, and Kitty as a team made a second pass and collaboratively added in the patterns.

The last consideration of Tom’s performance was that he didn’t feel compelled to use every single pattern available to him. He went out of his way to reuse work wherever he could. Kitty and Phoebe were far more impressed by this than if Tom had suggested a total rewrite, as many developers seem to want to do when they start at a new company.

In the next chapter, we’ll follow Tom, Kitty, and Phoebe as they writes the code that implements his diagrams.

Questions

  1. What are the advantages of diagramming a project instead of simply modeling everything in code?
  2. What is the one time we definitely use an abstract class instead of an interface?
  3. How did Tom leverage the Builder pattern to work with other patterns in the second pass of the design session?
  4. Can you think of any improvements to Tom’s design?

Further reading

Check out this book’s companion website at https://csharppatterns.dev.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset