Implementing design patterns is a great way to learn a new language. In my attempt to get a better understanding of Swift (and design patterns for that matter) I’ve decided to solve some of the real world challenges we face at YourMechanic using some of the more common design patterns. Of course some of these problems are worded rather conveniently to fit the specific design pattern :]
Who would find these articles useful:
These tutorials assume some working knowledge of Swift and general understanding of programming and object oriented fundamentals. However you do not need to be an expert in either Swift or design patterns to follow along. Since these articles combine two different subjects, individuals who are more versed in one and wish to learn more about the other would probably find these most useful. If you have an extensive background design patterns and come from a strong C#/Java background and want to get a feel for Swift, these articles would probably serve you well.
All solutions will come with an a link to the completed project on github.
If you spot any error or have and feedback I would love to hear it. This is my twitter
Design Patterns in Swift: Adapter
The problem:
YourMechanic is expanding to Canada. Now our friends to the north can have their cars fixed at their home or office by one of our professional mechanics. To finalize our expansion, we need to make major changes to our system. Providing support for the Canadian currency and the metric system would be a lot of work and we are short on time. Therefore we want an easy way to interface with our current Quote API. The Quote API can add and remove parts, set labor times for a quote, calculate a total price and track a car’s mileage. There also two properties, tax rates and labor rates which cannot be set but are derived from some external data source that we do not have access. All these values are assumed in USD/Imperial by our current system. We need a way to both display and input values in CAD and the metric system and have it remain consistent throughout our system. Also tax rates and labor rates are different in Canada so we need to adapt for those changes as well.
Design Patterns in Swift: Prototype
The problem:
Beside having qualified mechanics working for the general public, YourMechanic has several contracts with various businesses. The appointments for these jobs for the most part follow the same configuration (same mechanics, same set of services, same parts, same number of cars and prices). What’s different is the name of the client, the address and the start time. Building a corporate appointment over and over again with the same configuration is time consuming and heavy on our servers. We would like a solution where the same appointment type can be re-created without having to look up our mechanic directory, parts directory or service directory.
Design Patterns in Swift: Interpreter
The problem:
Our customers at YourMechanic request quotes through our website or through their YourMechanic App. The final price for a quote is a combination of two variables, the cost of parts and the cost of labor. We want the ability to apply specific adjustments to either parts or labor prices. These adjustments could come from coupons, gift certificates or discounts. We need a simple language that can express these custom adjustments. For example, we should be able to define an expression that can add a 20% discount for parts. Or a another code that reduces $10 on labor. Or one that does both.
Design Patterns in Swift: Chain Of Responsibility
The problem:
Not all mechanics are created equally. Some mechanics are more experienced and can do more than others. We need a system where every job is propagated from the least experienced mechanic to the most. This way experienced mechanics that can perform more jobs are not busy with jobs that more junior mechanics can take care of.
Design Patterns in Swift: Mediator
The problem:
Assume we track the location of all our mobile mechanics. We have noticed that there are times when a mobile mechanic might need assistance from another mechanic or a last minute need for a part that someone else might carry. We want to build a system where mechanics can send requests with the option of defining specific parts needed to all mechanics that are close to their location.
Design Patterns in Swift: Observer
The problem:
We have a set of mobile mechanics who are assigned specific zip codes. Each zip code has its own hourly rate. We want to increase and decrease these rates when the number of idle mechanics within a zip code falls or goes above specific thresholds. This way we can proactively set the going rate for each mechanic when demand is high and bring it down when demand is low within a specific zip code.
Design Patterns in Swift: Strategy
The problem:
We order our parts from three different vendors. Each vendor has its own system for fulfilling parts orders.
- ACME Parts Co which provides parts for domestic cars requires authorization from our parts supervisor before it can finalize any orders.
- PartsNStuff which provides parts for Asians cars requires each mechanic to provide their designated ID before finalizing orders.
- AutoPart Co which provides parts for European cars, as part of their state of the art secure ordering, sends us a number that we have to return true if even and false if odd before they can fulfill our orders.
We need a system that can fulfil mechanic’s order from all our vendors.
Design Patterns in Swift: State
The problem:
A quote goes through many phases before it is completed by a mechanic. Initially a customer request a quote, once received, our system attempts to automatically provide a quote for the customer. If our system doesn’t have enough information, the quote becomes pending. At this state a member of our customer support team finds out what’s needed to provide a ready quote. Once a quote is ready, the customer can use it to book an appointment. Once an appointment is booked a mechanic is assigned to the quote. We need to be able to retrieve this mechanic’s information. When the appointment is completed we generate a receipt and send it to the customer.
We need a system that can provide us with an interface to get the price, get a customized message that’s dependant on the quotes’s state, and provide the receipt when the appointment is complete.
Design Patterns in Swift: Visitor
The problem:
We send out an email and create an internal report when a quote is requested by the customer. We also do the same when an appointment is booked. The content of the email and the report are dynamically generated from the information contained in the quote and the appointment. We need a system that can provide us with an easy and straightforward way of composing these documents.
Ideally we hope to achieve this without adding repeated report/email functionality to our already cluttered Quote and Appointment class.
Design Patterns in Swift: Builder
The problem:
Our customers at YourMechanic request quotes through our website or through their YourMechanic App. A quote is a complicated object. It must have a car, at least one service, the customer’s contact information, a mechanic capable of doing the services, picked automatically by the system or selected by the user and a coupon code that a quote may or may not have. We need a system that can build our quote and guarantee its validity. The system should be extendable and capable of dealing with changes to our quote creation process, ideally without having to change anything in the quote object itself.
More to come…