‫Welcome back.
‫In this lecture, we're going to talk about gathering,
‫classifying and analyzing requirements
‫as the first step in designing a large scale system.
‫But before we get into any details,
‫let's first get some motivation.
‫System requirements is just a formal word for figuring out
‫and narrowing down what exactly we need to build
‫for our client.
‫As software engineers,
‫we shouldn't be new to receiving informal requirements
‫for the task we need to accomplish.
‫But when it comes to the design of a large scale system,
‫there are a few differences
‫from the usual requirements we are used to getting
‫for implementing a method, an algorithm or a class.
‫The first difference is the scope
‫and level of obstruction of the requirements
‫and especially the solution we need to design.
‫For example, when we're tasked to implement a method
‫or an algorithm in an existing code base,
‫we typically know what the input and output look like.
‫We are also somewhat limited
‫to the programming languages we're going to use.
‫As we go up to a more high level obstruction
‫like designing a class, a module,
‫a library or an application,
‫the range of possible ways
‫to solve the problem becomes bigger and bigger
‫as we have more degrees of freedom.
‫Also the scope of the problem becomes so high
‫that it's hard for us to even visualize the implementation.
‫So when we are asked to design an entire system
‫we may feel so overwhelmed
‫that we may not even know where to begin.
‫For example,
‫imagine you are asked to design a file storage system,
‫a video streaming solution, or a ride sharing service,
‫it needs to scale to serving millions of users per day.
‫It's hard not to get overwhelmed by such a task.
‫The second challenge and difference
‫from what we're normally used to is the level of ambiguity.
‫The reason for this ambiguity is twofold.
‫First of all, in many cases,
‫the requirements are not even coming from an engineer,
‫and sometimes they're not even coming
‫from a very technical person.
‫So the client or product manager
‫may ask for something very high level.
‫And it's our responsibility to transform those requests
‫into precise and technical requirements.
‫Those technical requirements will serve
‫as the foundation for building our software architecture.
‫The second reason for the high level of ambiguity
‫is getting the specific requirements
‫is already part of the solution.
‫This may seem a little odd for us at first,
‫but we have to remember
‫that the client doesn't always know exactly what they need.
‫The only thing they know for sure is the problem
‫they need to solve.
‫To demonstrate this, let's take a specific example.
‫Let's say we're asked to design a hitch hiking service
‫that allows people to join drivers that are already driving
‫on a particular route,
‫and are willing to take passengers on their way for a fee.
‫That may be all the requirements we get from the client,
‫and it is up to us to ask things like,
‫is it going to be a real time service
‫or the riders will have to contact the drivers in advance,
‫is it going to be a mobile
‫or desktop experience or maybe both,
‫are we going to enable payment through our system
‫or the riders will have to pay the drivers directly?
‫In some cases, the client may not even know the answer
‫to those questions right away
‫until we actually ask those questions.
‫That is why in most system design interviews,
‫one of the things being tested is our ability to clarify
‫and ask those questions ahead of time.
‫Because as we can see,
‫asking those questions and gathering those requirements
‫is already part of the solution and it greatly narrows down
‫what we need to design and build.
‫Now, what happens
‫if we don't get all the requirements right?
‫Can't we just do it incrementally?
‫Why can't we simply build something
‫and see if it satisfies the client?
‫And if it doesn't, no big deal.
‫We can just fix it, can't we?
‫After all, we're not building a building or a bridge here.
‫There's similarly no big cost of materials in software,
‫like in mechanical engineering, for example,
‫or construction of a building.
‫Well, the mental leap we need to make here
‫from small projects like building a method or a few classes
‫where we can easily rewrite the code many times
‫until we get it right,
‫large scale systems are big projects
‫that cannot be changed easily overnight.
‫Those projects take many engineers,
‫sometimes even multiple teams of engineers.
‫They can take months to build,
‫which makes the cost of engineering time very significant.
‫They also often require purchasing hardware
‫and sometimes software licenses upfront.
‫And those projects typically involve contracts
‫with time commitments and financial obligations.
‫Also not delivering the product to our clients
‫or users on time may cause irreversible damage
‫to our company's reputation and brand image,
‫so getting the requirements right upfront
‫is absolutely critical.
‫So now that we got the motivation for system requirements,
‫let's take a step further
‫and learn to classify the requirements
‫into a few categories,
‫which have completely different effects
‫on our architecture and design.
‫The three main types of requirements
‫are features of the system,
‫also known as functional requirements, quality attributes,
‫which are also known as non-functional requirements,
‫and system constraints, which basically the limitations
‫and boundaries of the system.
‫Let's start talking about the first type of requirements,
‫the features of the system.
‫Those requirements essentially describe
‫the system's behavior.
‫In other words,
‫what the system we're designing actually does.
‫Those requirements are easily tied
‫to the objective of the system.
‫They are also called functional requirements
‫because they essentially describe our system
‫as a black box function.
‫The user's input or external events are the inputs
‫to that function,
‫and the result or outcome of the operation taken
‫by our system is the output of that function.
‫It's important to point out that the features
‫or functional requirements simply dictate the functionality
‫of our system but do not determine its architecture.
‫And generally any architecture can achieve any feature,
‫which is what makes our job
‫as software architects so difficult.
‫Now, let's look at a few examples
‫of features or functional requirements
‫in our hitchhiking service example.
‫One functional requirement can be as follows,
‫when a rider logs into our mobile app,
‫the system must display a map with nearby drivers
‫within five miles radius.
‫Here the input to our system is the user's login action,
‫and the output is the view of a map with nearby drivers.
‫Let's take another example.
‫When the ride is complete,
‫the system will charge the rider's credit card
‫and transfer that money to the driver
‫minus some service fees.
‫Here the completion of the ride is the input event,
‫and the transfer of the money
‫is the outcome of the operation.
‫Now, let's talk about the second type of requirements,
‫the quality attributes or non-functional requirements.
‫The quality attributes are properties
‫that the system must have
‫as opposed to what the system must do.
‫Examples of such qualities include scalability,
‫availability, reliability, security, performance,
‫and this list can go on and change depending on the system.
‫In contrast to the functional requirements,
‫the quality attributes do dictate the software architecture
‫of our system.
‫Another way to look at this is, the software architecture
‫defines the system quality attributes.
‫And different architectures provide us
‫with different quality attributes.
‫The last type of requirements is system constraints.
‫A few examples include strict deadlines, limited budget,
‫or a small number of engineers that can work on our project.
‫Such constraints may force us to make certain trade offs
‫and sacrifices in our design and shift us
‫towards certain software architectural decisions
‫that we would not make if we didn't have those constraints.
‫The three types of requirements that we learned
‫in this lecture are also sometimes referred to
‫as architectural drivers.
‫Because they essentially drive our architectural decisions
‫from an infinite universe of possibilities
‫towards one solution that satisfies our clients' needs.
‫In this lecture,
‫we learned about the importance of requirements
‫in the design of large scale systems.
‫We discussed the few challenges
‫of gathering those requirements,
‫such as the large scope
‫and ambiguity that we may not be familiar with
‫coming from a smaller scale programming world.
‫After that, we talked about the risks
‫of not getting those requirements correctly upfront.
‫And finally,
‫we classified those requirements into three groups,
‫which are also called the architectural drivers
‫of the system.
‫Those three groups are the features of the system,
‫the quality attributes and the systems constraints.
‫See you guys all in the next lecture.