UML and Object-Oriented Design Foundations | Karoly Nyisztor | Skillshare

UML and Object-Oriented Design Foundations

Karoly Nyisztor, Senior Software Engineer, Instructor

UML and Object-Oriented Design Foundations

Karoly Nyisztor, Senior Software Engineer, Instructor

Play Speed
  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x
38 Lessons (1h 49m)
    • 1. Course Overview

      3:36
    • 2. 1.1 Introduction

      3:06
    • 3. 1.2 Prerequisites

      1:07
    • 4. 2.1 Software Development Methodologies

      1:40
    • 5. 2.2 The Waterfall Model

      4:07
    • 6. 2.3 Agile

      4:24
    • 7. 2.4 Waterfall or Agile?

      1:49
    • 8. 3.1 Brief History of Programming

      3:47
    • 9. 3.2 Objects

      2:15
    • 10. 3.3 The Class

      2:21
    • 11. 3.4 Abstraction

      1:24
    • 12. 3.5 Encapsulation and Data Hiding

      2:32
    • 13. 3.6 Inheritance

      3:18
    • 14. 3.7 Polymorphism

      4:06
    • 15. 4.1 Fundamental Object-Oriented Analysis and Design Concepts

      3:16
    • 16. 4.2 Collecting Requirements

      4:01
    • 17. 4.3 Mapping Requirements to Technical Descriptions

      4:10
    • 18. 4.4 Why Do We Need a Common Descriptive Language?

      1:10
    • 19. 5.1 What's UML?

      4:00
    • 20. 5.2 Use Case Diagrams

      3:35
    • 21. 5.2.1. Use Case Diagrams: Challenge

      1:03
    • 22. 5.2.2 Use Case Diagrams: Solution

      3:00
    • 23. 5.3 Class Diagrams

      3:36
    • 24. 5.4 Visibility: Public, Private, Protected, Package

      3:30
    • 25. 5.5 Associations

      2:49
    • 26. 5.6 Generalization

      1:33
    • 27. 5.7 Visibility: Public, Private, Protected, Package

      2:30
    • 28. 5.8 Sequence Diagrams

      4:40
    • 29. 5.9 Activity Diagrams

      2:50
    • 30. 5.10 Statechart Diagrams

      1:37
    • 31. 6.1 Case Study: Designing a Note-Taking App from Scratch - Collecting the Requirements

      2:00
    • 32. 6.2 Creating User Stories

      2:24
    • 33. 6.3 Diagraming the Main Use Cases

      3:02
    • 34. 6.4 Modeling the Classes and the Relationships

      6:14
    • 35. 6.5 Describing the Flow of Note Creation using Sequence Diagrams

      2:15
    • 36. 6.6. Modeling the States of a Note Object

      3:03
    • 37. Goodbye!

      1:05
    • 38. Q&A - How to Create Associations in Use Case Diagrams using StarUML

      1:44
  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels
  • Beg/Int level
  • Int/Adv level

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

577

Students

--

Projects

About This Class

Explore the fundamental concepts behind modern, object-oriented software design best practices. Learn how to work with UML to approach software development more efficiently.

In this comprehensive course, instructor Károly Nyisztor helps to familiarize you with the fundamentals of object-oriented design and analysis. He introduces each concept using simple terms, avoiding confusing jargon. He focuses on the practical application, using hands-on examples you can use for reference and practice. 

Throughout the course, Károly walks you through several examples to familiarize yourself with software design and UML. Plus, he walks you through a case study to review all the steps of designing a real software system from start to finish.

Topics include:

  • Understanding software development methodologies

  • Choosing the right methodology: Waterfall vs. Agile

  • Fundamental object-Orientation concepts: Abstraction, Polymorphism and more

  • Collecting requirements

  • Mapping requirements to technical descriptions

  • Unified Modeling Language (UML)

  • Use case, class, sequence, activity, and state diagrams

  • Designing a Note-Taking App from scratch

You will acquire professional and technical skills, together with an understanding of object-orientation principles and concepts. After completing this course, you'll be able to understand the inner workings of object-oriented software systems. You will communicate easily and effectively with other developers using object-orientation terms and UML diagrams.

Meet Your Teacher

Teacher Profile Image

Karoly Nyisztor

Senior Software Engineer, Instructor

Teacher

My passion is helping people through online courses. So far, I've inspired over 50,000 students worldwide.

Hi there, my name is Károly Nyisztor. I'm a software engineer, online instructor, and book author. You can find my courses and books on all major platforms including Udemy, LinkedIn Learning, Lynda and Pluralsight.

I've worked with companies such as Apple, Siemens, SAP, Zen Studios, and many more. 
I've designed and built several enterprise frameworks, and I hold twelve patents related to inventions in the field of mobile computing.

I've developed over a dozen iOS apps and games- Libra Balance, My Travel Assistant, Travel Mate, iSyslog, GiftShopper, Zombie Run, to name a few.
Most of these apps have been featured by Apple(New a... See full profile

Class Ratings

Expectations Met?
  • Exceeded!
    0%
  • Yes
    0%
  • Somewhat
    0%
  • Not really
    0%
Reviews Archive

In October 2018, we updated our review system to improve the way we collect feedback. Below are the reviews written before that update.

Your creative journey starts here.

  • Unlimited access to every class
  • Supportive online creative community
  • Learn offline with Skillshare’s app

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

phone

Transcripts

1. Course Overview: Would you like to design complex applications? Do you know how to model object-oriented systems efficiently? Maybe you plan to become a software architect or you want to refresh your knowledge about UML and object orientation. Programming is not only about coding. You learn the basics and implement some code. As you create more complex apps, it becomes harder to keep all the details in your head. You keep staring at the code you wrote yesterday or a week ago, trying to understand what you did and why you did it that way. Sounds familiar. Everyone who learns to program finds himself or herself in this situation eventually. And that's why I created this course. Hi, I'm Cairo in your store and welcome to UML and object-oriented design foundations. This is the perfect course to get you started thinking in object-oriented ways. I'm going to walk you through all the important aspects and concepts of the object-oriented software design. We're going to start with software development methodologies. Understanding the difference between the waterfall and an agile methodology can make or break your project. Will then talk about ideas like classes, Abstraction, Composition, polymorphism, and many more. These are the fundamental concepts of object oriented software design and development. You will learn that the various steps of the object-oriented software analysis and design process, mastering these concepts will let you design your software systems more efficiently. Within dive into UML, you'll learn about the core UML concepts and the fundamental UML diagram types. We start with a use case diagrams, the primary way of describing the requirements in a formal way. We continue with the sequence diagrams that can express the flow of logic using simple visual artifacts. Then I'll introduce the class diagrams used to represent the main types that former system and the relationships between them. We continue with the activity diagrams, which let us capture the message flow between activities. Last but not least, we'll talk about as a state diagrams, which are unintuitive way of describing finite state machines. They represented the state transitions of an object. Finally, we'll solidify the concepts you learned by designing a real application from scratch. In this exercise, we follow the phases of the object oriented design process. In the end, we'll have collected the requirements, written Use Cases, and various UML diagrams describing the static structure and the behavior of our application. By the end of this course, you will become familiar with the fundamental object-oriented design concepts. The techniques described in this course have real practical value. You will be able to apply them in your upcoming projects. Not only will I cover the details of all of these topics, but you'll also find quizzes to verify our knowledge. If you have any questions, don't worry, I offer fast and friendly support through the forums. Now, this course is a long time investment. Go ahead and click the enroll button and see you in the first lesson. 2. 1.1 Introduction: Hi, I'm cargo, any store and welcome to my course UML and object oriented design foundations. The main goal of my course is to avoid the situation when you stare at your favorite I d. Without knowing what to do next. Let's first talk about the motivation behind studying UML. After learning the basic syntax of a programming language, we usually start writing some code. Eventually, we realized that creating real world applications requires additional skills. Mastering the syntax of a programming language is not enough. We must also know how to design the software system by applying common object oriented principles. And we must be able to describe our design so that others can understand it. Clearly, The unified modeling language provides a standard set of visual symbols and diagramming techniques. Using UML, we can sketch our systems easily. This course is all about UML and software designed related concepts. Now the steps required to create a software system are not carved in stone, yet attempts have been made to formalize the process. We're going to discuss the waterfall and the agile approach. Object orientation has been around since the eighties, but its principles are still valid and used in modern software design, I dedicated an entire section toe the fundamental object orientation concepts. Next, you learn about the various steps of the object oriented software analysis and design process. Mastering these concepts will let you design your software systems more efficiently. Then we'll dive into UML. This UML introduction will make it easier for you to understand the upcoming detailed lectures. Next, I'll introduce the most popular UML diagram types. We start with the use case diagram that lets has described the requirements in a former way . Then we discuss of a class diagram. Class diagrams can model the main types that former system and the relationships between them will also talk about sequence Diagrams that can be used to represent the dynamic behaviour of your objects were then, discuss the activity and the state diagram. To solidify the concepts you learned. I'm going toe walk you through the steps of designing a note taking application. We'll start by collecting the requirements, then will create the youth case diagrams. After identifying the main entities will model the class diagrams you're going toe. Also see the sequence and the state diagram in action. All right, we've got lots of exciting things to cover, so let's move on 3. 1.2 Prerequisites: Now, before starting the course, you should be aware of some prerequisites. This course is beginner friendly. I explain each concept clearly and illustrated using practical examples. So you don't have to be an expert by any means, but you should have at least fundamental programming knowledge. I'll be using basic concepts like for example, conditions, functions, loops, and I assume you understand them. Download star UML if you want to follow along with me the creation of the UML diagrams in this course. It is available for Mac, Linux, and Windows at starting with ML dot IO. Although we won't be writing any source code, I'll show you some code examples. I use Adam, free and open source text and source code editor developed by GitHub. It is available on Atom dot io, and it runs on Mac OS, Linux, and Microsoft Windows. All right, let's get started. 4. 2.1 Software Development Methodologies: There are different ways to develop a software system. Sure, you can just sit down and start typing source code. This works until, well, it doesn't. For anything more complicated than Hello World app, you will need a way to organize your work. And if you're not working alone, the lack of a reasonably well-defined processes going to lead to chaos as the complexity of a project and the number of people increases, the need for a development process becomes more and more prevalent. Different approaches have been invented to solve this situation. We're going to talk about two of the most popular development methodologies, namely the waterfall model, which requires you to have a detailed plan before starting any coding. The requirements need to be fixed, so no changes are expected during development. And the second one is the change friendly, responsive agile approach, which works great for projects where the expectations can change rapidly and frequently. Now, before we delve into these methodologies, I must tell you one thing. None of these systems can precisely describe every step of the software development process. But we definitely need them to synchronize and organize our development related activities. Activities that include not only coding, but also design, product management, budgeting, testing, documentation, release, and maintenance. 5. 2.2 The Waterfall Model: The waterfall is a linear model. It defines development steps or phases. You start executing one step completed, and then start the next one. This approach gives us a steady downward order, hence the name waterfall. The development process flows in Cascades. Each development phase requires the previous one to be completed. Let's talk a bit about these phases. First, we collect and analyze the requirements. The expected functionality of the future application must be clarified with the stakeholders, are the details must be documented thoroughly. The very first phase is probably the most important one. When done right, the waterfall model will produce the expected outcome. After collecting and analyzing the requirements, we can proceed to the next phase. Here's where we defined the overall design of our software. Defining the architecture is like creating the blueprint for a building. Thus, the design should be as clear and detailed as possible. The team should be able to implement the product based on this plan, we should address questions like, what packages or components with a form our system. What are the fundamental types of each component? How do these types interact with each other to achieve the required functionality? Is our software secure? How about performance? How does our software respond to errors? How do we handle the edge cases? Should we extend our system in the future? What third party components do we use? And the list can grow or shrink depending on the requirements we defined in the previous phase. The implementation comes next. The software development phase is usually divided into smaller units. Each unit is then implemented and tested by developers. Once the development phase is completed, the product undergoes the verification phase. During this step, the software is evaluated based on pre-defined criteria. We must check whether the product provides the functionality we agreed on. Tests are executed to ensure that the software works as expected. We test for functional performance, security and usability issues. Detected problems are recorded and fixed. The process goes on until all severe bugs are fixed. The verification phase may also bring to surface deeper bugs and critical issues that may affect the planned release. Now, when the testing phase completes and the given version is delivered, the software enters the maintenance phase. By definition, the maintenance phase is about fixing smaller bugs. But more often than not, it may also include functional enhancements. The client may come up with new requirements that involve substantial changes. You may feel tempted to squeeze in just one more PECC in the maintenance phase. This is usually a bad idea. Instead, you should set up a new waterfall project and repeat all the steps. The waterfall model is used for live control, magical, and military systems. This model requires us to clarify all the requirements and create a detailed plan upfront. The waterfall is a perfect choice if all the requirements are precisely defined and won't change over time. Now, the waterfall has received some criticism for its inability to respond to changes due to its linear structure. New requirements can be considered at later phases of the development process. If the client changes their mind frequently or are designed Mrs. essential aspects, we're going to hit problems during development or testing. In such cases, we should follow a different approach. 6. 2.3 Agile: Agile is a relatively new approach to software project management. It all began with the Agile Manifesto in 2001. This manifesto was an attempt to end the proliferation of methodologies that had developed. The Agile Manifesto defines four values, individuals and interactions over processes and tools. This doesn't mean that we won't use processes and tools in Agile projects were still need tools and processes, but they shouldn't prevent us from implementing the required features or changes. Instead of enforcing people to follow a rigid process, we implement a process that adaptive and responsive to changes. The second principle, working software over comprehensive documentation. This doesn't mean that Agile projects don't use documentation at all. We should create documentation where it provides value. There is no need to create extensive documentation just for the sake of it. The third principle, customer collaboration over contract negotiation, don't get this wrong either. Agile projects also require contracts to manage customer expectations about costs and schedules. Yet, unlike for plan-driven projects, there is a spirit of partnership between the development team and the customer. Due to the somewhat uncertain nature of Agile projects, both parties acknowledge that some requirements and details may need to be redefined or clarified further as the project progresses. It goes without saying that this kind of partnership requires collaboration and trust. The next one, responding to change over following a plan. Agile is different from plan-driven approaches and provides more flexibility compared to the waterfall model. The major difference is that agile welcomes changes even at the later phases of the development cycle. Some planning is also required for Agile projects, but we don't try to come up with a detailed plan for the entire project before starting any development activities. As a consequence, we're not blocked until all the requirements are defined and each and every question gets answered. Now, let's talk about how an agile approach solves the problem we saw with the waterfall. The main idea behind Agile is that we can provide functional software either actively instead of delivering the entire project all at once. The work is broken up into shorter chunks called sprints. The sprint is usually two to four weeks long. At the end of each sprint, the team should deliver a version that's an improvement over the previous sprints outcome. This interactive approach provides an opportunity to frequently review is a product that's being developed. Stakeholders have a chance to evaluate the software, provide their feedback early on rather than waiting for the final product to be delivered. These frequent checkpoints are super useful as they ensure that the project evolves in the right direction. Unlike the waterfall, agile methodologies do not separate testing from development. Testing is tightly integrated with the development and the entire team owns the responsibility afforded the quality of the product. Also involving the business users in the development process stands at the core of Agile approaches. There's a strong relationship between the project team and the stakeholders and business users. This model works best in situations where the requirements can't be defined up front. Agile is a good fit for software projects that are depending on many uncertain factors and changes are to be expected. One of the big benefits of this collaborative model is that it usually leads to higher customer satisfaction and team members will likely be more motivated by engaging customers directly. Note that Agile is not a methodology, but rather a way of thinking defined by the Agile Manifesto values and principles. Scrum and Kanban are examples of discrete methodologies that implement the Agile approach. 7. 2.4 Waterfall or Agile?: Waterfall is usually perceived as rigid and bureaucratic compared to agile methodologies. However, both have their place. There are cases when a plenary one methodology won't work. If the level of uncertainty is high and not all questions can be answered right away, then you should probably choose an agile methodology for other projects. Waterfall approach will be a better fit. Let me give you some examples. When developing a weapons control system, the requirements should be clarified in advance and need to be stable. Changing the requirements Midway would increase the costs considerably. And these kinds of projects are expensive and they weigh. A waterfall approach makes perfect sense in this case. Here's another actually real example from Upwork looking to create the next big social media platform for iOS and Android. Now, coming up with a detailed plan based on assumptions wouldn't make sense. In this case, the description is vague and the customer won't be able to describe precisely what they want. This high level of uncertainty calls for an agile approach, or rather just skip this project. Creating the next big social network will require multiple iterations. So to sum it up, you should use the waterfall when you know what the final product should be. And clients can't change the scope of the project. Agile methodologies should be used when there's a lot of uncertainty involved. The requirements are vague or rapidly changing and clients can precisely describe what the end product should do or look like. 8. 3.1 Brief History of Programming: Programming was totally different a couple of decades ago. Nowadays, it is easy to get started with programming. There are various visual tools and sophisticated development environments that make learning fun. We can program drones and robots, create 3D games or augmented reality apps. We can achieve on that without having to learn for the years. We're lucky to have all these great tools today. Initially, computer programs were big, contiguous chunks of code. The unstructured programming was the earliest programming paradigm. The code consisted of sequentially ordered instructions. Each statement would go in a new line. Source code lines were numbered or identified by a label. Here's an example of written in Sinclair basic. The simple program converts from Fahrenheit to Celsius degrees. As the programs grow in complexity, the drawbacks of this approach had become apparent. Maintaining or even understanding such a code-base was challenging. To make any changes or improvements, you had to check the statements line by line. This task becomes more and more difficult as the number of code lines increases. Non-structured programming was heavily criticized for producing hardly readable so-called spaghetti code. The term spaghetti code is a pejorative description for complicated, difficult to understand, and impossible to maintain software. Structured programming emerged in the late fifties. Structured programming languages breakdown code into logical steps. They rely on subroutines which contain a set of instructions to be carried out. Here's an example of a program written in C, which is a procedural language. The function called main is at the entry point of our program. It calls the sum function to add the two numbers entered by the user. And we can define additional functions. For example, if we need to calculate the average of two numbers, we could create a function like this. The subroutines operate on variables and data structures. Now, what's a variable? A variable represents a value of a given type that can be identified using a name. We use the name of the variable to access the stored value. This lets us read or modify the value during run-time. A data structure is a way of organizing and storing data in a computer program. Here's a structure that aggregates the information needed to represent an employee. Structured programming was a significant improvement compared to the monolithic coding practices named functions, improved readability of the computer programs. The development times could be reduced substantially. Even with the improved quality, developers started to face new challenges as the programs got bigger and bigger, structured programming could not address all the increased complexity. Object-orientation was the next big step in the evolution of the programming paradigms. Object-oriented languages appeared in the eighties. The main idea was to split apart is a program into self-contained objects. Each object represents a part of the system that gets mapped to a distinct entity. Basically, an object functions as a separate program by itself. It operates on its own data and has a specific role. The objects that formed the system interact with each other. Object-orientation aims to bring the world of programming closer to the real world. 9. 3.2 Objects: While structured programming relies on actions, object-oriented programming is organized around objects. An object represents a thing. Just like in real life, objects can be simple or complex. A golf ball is an object, but so is Falcon Heavy. The way we define an object depends on the level of detail we need. With the launch of the Falcon Heavy. They also send the Tesla Roadster with Star Man in the driver's seat toward Mars orbit. Objects may contain or referred to other objects. This can also happen in the object-oriented world. We can describe objects using their properties. They can have attributes like name, color, weight, and velocity. A golf ball can be completely white colored or it may even glow in the dark. It has a weight and the price. Some properties like its position, speed, and acceleration can change, while other attributes, its color, for example, will stay the same. Or these properties describe an object in the real world. This approach works also in an object oriented language. Objects have their identity, their own state. Changing the state of one object doesn't change the state of other objects. If we hit a golf ball, it won't affect all the other bonds. There are. State is independent, each has its private identity. Besides properties and identity, an object has its own behavior. The behavior of an object is what it can do. The black dog barks. In this sentence, we identify one object. The dog bark is the behavior or the action performed by the dog object. And black is its color, one of its attributes. We can identify the object easily since it's the noun in the sentence. The verb is the behavior, and the adjective is the property. We describe an object using its properties, identity, and behavior, quite straight forward. But how can we make this work in our code? For that, we need to introduce a new concept, the class. 10. 3.3 The Class: Building an object oriented system starts by identifying the potential objects, their attributes, and responsibilities. We need to have a class before we can create an object. The class is the blueprint of an object. You can think of a class as a plan description of what an object will be. Let's say you want to use a Pokemon in your program. A class called Pokemon would provide a blueprint for what the Pokemon looks like and what it can do. The class tells us that each object has a name, armor level, and hit points. It doesn't say what the name or the armor level is. A Pokemon can attack and it can defend itself. These two actions define its behavior. We created a class by giving it a name and declaring its properties and actions. We call these actions methods. Methods are blocks of code that can be called to execute certain operations. They may take input parameters and can also return values. Methods are like functions in structured programming languages. The methods are basically functions embedded in a class. Given this class, we can create objects based on it. Upon object creation, we provide the values for the attributes declared in the class. Each object will have a name, armor level, and hitpoints. The attack and defend the behaviors are provided by the class. Given the blueprint, we can create as many instances as we need. Another big benefit of classes is that we can package them into libraries or frameworks. This lets us reuse them in other programs as well. All modern object-oriented programming languages provide such built-in frameworks and libraries. We don't have to reinvent the wheel by implementing functionality that's already available. Instead, we can focus on creating and using the objects in our programs. Now, each program has different requirements. The pre-made classes, we rarely cover all our needs. You'll often find yourself creating your own classes. We have now covered the object and the class. Next, we'll take a look at the core object orientation principles. 11. 3.4 Abstraction: Abstraction is a way of describing complex problems in simple terms by ignoring some details. Eliminating the mushy helps us focus on the bigger picture. We can dig deeper once we have a broader understanding how it does abstraction work. If I say cat, you know instantly what I'm talking about? I don't need to say I was thinking of a male Persian cat. If it's a kitten or if it's big or small. You understand that I was talking about a cat, we are naturally good at generalizing things. We can skip the irrelevant details and people will still understand us. That's because our brains are wired to understand abstract ideas like cat, house or car. Abstraction works the same way in the object-oriented world. When we start defining a class, we focused on the essential qualities and discard unimportant ones. Back to our Pokemon example. We started with the most important attributes and methods. We don't need details like age, weight, or height, so we can ignore them. These attributes are unessential in our current application. So that's how abstraction works. We focused on what's important and ignore all the details we don't need. 12. 3.5 Encapsulation and Data Hiding: The next fundamental idea to keep in mind when dealing with object-oriented programming and classes is called encapsulation. We encapsulate something to protect it and keep its parts together. Think of how medicine is enclosed in a shell called capsule. In object orientation, this translates to packing together our properties and methods in a class. Encapsulation also means hiding the gears and the levers. Here's an example. We can use a phone without understanding electronics. We don't need to know how the touchscreen, the camera, or the logic board works. Similarly, we don't want to expose the inner workings of our class. An object should only reveal the essential features. This concept is called data hiding. By hiding the internal details, the object is protected from external interference. Basically, we restrict clients from modifying the object in ways we did not originally plan whether it's intentional or accidental. Additionally, we prevent other parts of the system from relying on properties or behavior that may change. If you replace your phone's battery, it won't affect the way you use your phone. That's because you only interact with the touchscreen. Changes in the inner workings of your phone don't matter to you. Our classes shouldn't be any different either. If we expose unnecessary details, any changes to those attributes or methods may affect other parts of the system. Whereas if we restrict access to that data or behavior, we don't have to worry about the ripple effects of our changes. Data hiding is not about selfishly keeping stuff for ourselves. Rather, it's about protecting our classes from unwanted external dependencies. As a rule of thumb, expose only as much of your class properties and methods as needed for normal usage. Data hiding place on essential role in keeping the dependencies between objects to a minimum tightly coupled system with most of the objects, depending on each other, is an obvious sign of a bad design. Updating or maintaining such a system is a pain. Any tiny modification will cascade down and require you to change other parts of the system to, it's like a never-ending nightmare. Object-oriented programming principles are here to make our lives easier. Next up is the idea of inheritance. 13. 3.6 Inheritance: Inheritance is a key concept in object oriented programming. Without inheritance would end up writing similar code over and over again. Inheritance means code reuse. That is, reusing existing class implementation in new classes. Let us start with an example. We modeled the Pokemon class with the main properties and behavior in mind. Given this class, we were able to create our Pokemon instances. Now what if we need new types like electric water or flying Pokemon? We will need new classes. Since these new types have special abilities. For properties, the Pokemon class has name, armor and hitpoints, and it can attack and defend itself. The electric, water and flying Pokemon have all these properties and they are also able to attack and defend themselves. Additionally, they have specialized functionality and electric Pokemon has the ability to wide charge. This attack is only available to electric dipole came on. Aqua tail is a damaging water Pokemon move and flying Pokemon convert form the dragon essence attack. As you've probably realized, the three new classes are almost identical to the Pokemon class. The only difference is the special attack type. We could add all these new behaviors to the Pokemon class. If we did that would end up in a class that has too many responsibilities. Suddenly, all Pokemon objects could swim and fly and discharge electricity. We definitely don't want that. Our classes should be simple. They need to have a well-defined purpose. Object orientation is about granularity and separation of concerns. Each class should focus on a set of specific functionalities and do that well. Creating one size fits all monolithic classes is a major mistake in object-oriented software development. So how about keeping these glasses separate? That sounds better, but now we keep repeating the same code for common functionality, there must be a better way. Indeed, object-oriented programming languages have a solution for this kind of problem. Inheritance. A class can inherit all attributes and behavior from another class. In our case, we let electric Pokemon, water Pokemon, and flying Pokemon inherit from the Pokemon class. The data and the behavior from the Pokemon class are now available to all these classes without us having to write a single line of code. Now we can add specialized behavior or attributes to the classes that inherit from Pokemon. If we enhance or modify the Pokemon class are the other classes will automatically receive those changes. In object-oriented terms, Pokemon is a parent or superclass, whereas the electric Pokemon, water Pokemon and flying Pokemon are subclasses or child classes. Inheritance is a powerful idea that can save us from a lot of extra typing. And finally, it paves the road to another handy feature called polymorphism. 14. 3.7 Polymorphism: Here's another term you will often hear when it comes to object-orientation polymorphism. The word has Greek origins and it consists of two words, polys, which means many, much and more Fei, meaning form, shape. If you look up the word polymorphism, you will find the following definition. The condition of occurring in several different forms. But how does this apply to programming? To understand how polymorphism works, we have to revisit the idea of inheritance. Here's our Pokemon superclass and its subclasses. The electric, water and flying Pokemon, all inherit the data and the behavior of their superclass. So they have a name, armor, hitpoints, and they can attack and defend themselves. The water Pokemon inherits the attack behavior from the Pokemon superclass. Now, what if we need water Pokemon types to cause more damage than basic Pokemon? For that, we need to provide the specialized implementation of the attack behavior. This is what we call method overriding. By overriding a method of the superclass, we tell that we want a different behavior in our subclass than the one we inherited. Method overriding is straightforward. We re-implement the method with the same name and parameters as the one defined in the parent class and provide our own behavior. By doing so, the water Pokemon objects will have a different attack behavior than they are Pokemon superclass. Calling the attack method on the electric and flying Pokemon objects will use the logic implemented in their superclass, since we did not override it, the attack method in their case. So that's method overriding. Polymorphism lets us work with objects created from any of these classes. We don't need to know whether it's a water flying or electric Pokemon instance to call any of the common methods defined in the superclass, we could create an army of mixed Pokemon and tell them to attack at once. Each of them will execute the right attack method without us having to know their exact type. All we know is that they are all instances of the Pokemon type or one of its subclasses. Polymorphism is about working freely with instances of many different classes that share a common superclass. It's probably easier to grasp it when using it in a real program. So let me show you an example. I'm going to use Swift and xcode on a Mac will implement the Pokemon class and all the subclasses. This is an overly simplified example. Matt is good enough to show you how polymorphism works in a real program. So here's our Pokemon class. The attack method just displays a message to the console. The electric, water and flying Pokemon classes inherit from the Pokemon class. And this is how we do it in Swift. We put the name of the superclass after the name of the child class separated by a colon. I override the attack method in the water Pokemon class. To specify that I'm overriding a method in the superclass, I use the override keyword. For this example, we'll simply display a different message. Next, I'll create some Pokemon instances. One Pokemon object, water polo came on than an electric and a flying Pokemon two. Then I define a list with these objects. Now, I can traverse this list and cause the attack method on the objects in the list. We don't need to know the class. They were instantiated from. Now if I run the demo with a seed that the attack method produce the same output in the console for all the objects. But one, that object was of type water Pokemon, the one which overrides the attack method. 15. 4.1 Fundamental Object-Oriented Analysis and Design Concepts: Building an object-oriented application requires some preliminary steps. The steps are similar regardless of the development methodology. First, we need to collect the requirements. During the requirements collection phase, we answer the following questions. What is the problem we're trying to solve? What does our app or framework need to do to accomplish that functionality? The requirements collection step involves a lot of brainstorming and discussion. Once we come to an agreement, we need to document our ideas. The requirements need to be as clear as possible. Only write down the decisions that underline what the system is going to do. Vague thoughts will lead to conflicts later on. Once the requirements are clear, we come up with a description of the software system. We should describe the app from the user's perspective. Depending on the project, we may pick an agile or waterfall methodology. For Agile projects, it is completely fine. If we don't provide an accurate description. We can still feel the gaps or refine our thoughts later on. The point here is to gain as much clarity as needed to start the next step. The step of describing the app may include the creation of visual mockups, wireframes, even prototypes. If it helps in communicating your thoughts to the client, then do it. I've used wireframes and nonfunctional prototypes for most of my projects. These prototypes proved to be extremely useful, especially if the client was not familiar with the platform or they had no specific expectations. Let's say a customer asks you to create an iOS version of their Android app. A prototype will help the client understand that the iOS version will look and behave differently by communicating our vision precisely, we avoid surprises and misleading expectations. Next comes the third phase. During this step, we aim to identify the things that form our system. These are the potential players that have a specific, well-defined role in our application. Picking the essential entities won't be challenging if we did a good job during the previous two steps, will realize that we need a class that represents, say, an item that has a name, a price, and some other attributes, or a class responsible for securely communicating with the server. Another classmate manage your local persistence and so on. In the final phase, we describe the behavior of our system in a formal way. This last step is about creating visual representations of our classes, their attributes and behavior. We also model the interaction between the objects will rely on the Unified Modelling Language, or UML for short. Uml is a form of graphical notation that provides a set of standard diagrams. These diagrams let us describe object-oriented systems in a standard way. I know this may sound overwhelming now, but don't worry, we're going to discuss each of these concepts in the upcoming lectures. 16. 4.2 Collecting Requirements: The initial step of building a software system is crucial. It's often called the requirement collection phase or requirements analysis. But regardless of what we call it, it paves the way for all the other phases of the object-oriented software design. Requirement means a thing that is needed or wanted. And that's exactly what we need to focus on during this initial step, we must clarify what's needed or wanted in our application. The features of the system are the so-called functional requirements. Functional requirements represent what the app needs to provide feature wise, it should react to a particular input or what the expected behavior is in a specific situation. Let's say you're about to develop an app for runners. You should answer questions like the following. Should the actual speed always be visible on the main screen? Do we allow imperial or metric units? Should we make this configurable by the user or automatically adjusted the units based on the phone settings instead. Will also usually have non-functional requirements. These are the requirements that are not directly related to a feature or behavior of the software system, but are important nonetheless. Think of performance requirements. You don't want to read in the user experience with an unresponsive app. You also may need to address a legal requirements. Does the app collect sensitive user data? Does it allow users to browse the Internet? Documentation and support our other non-functional requirements. Your software may need to adhere to certain standards or regulations. Non-functional requirements are equally important. Ignoring them may cause serious legal issues and all sorts of other problems. Now, how do we handle this? There are different ways to gather the requirements. The easiest way is just to write them down. Here's an example from a project I've been working on. Functional requirement. The atmos store travel expenses organized by trip. Each trip must have a home currency. The default currency is fetched from the phone settings. User settings must override the default home currency. Expenses can be entered in any of the supported currencies. The app must automatically convert the amounts to the home currency. Non-functional requirements. The atmos run on iOS 9 and newer versions. The app must avoid unnecessary network round trips to reduce data roaming fees and preserve battery. The app must include the support email, and a link to the APS website. These are short, concise phrases in the form the app or system must do this or that. You don't want to write lengthy descriptions and feel free to adapt to this format to your needs. You should eventually captured your requirements digitally by the early stages, pen and paper or a whiteboard are also fine. Just make sure you save them somehow by taking a photo, for example. There are also more formal ways, tools and systems that support the requirements collection step. I won't talk about these tools because this course is not about tools, but rather about principles. To summarize the requirements collection step boils down to this. We need to formulate what our software must do and which are the constraints and boundaries we need to consider. If we're using a waterfall approach, we need to clarify all the requirements in advance for Agile projects. It's perfectly acceptable if we continue without having all the answers. We may even miss some of the questions. Agile, let us revisit and refine the requirements as we iterate through the software development process. 17. 4.3 Mapping Requirements to Technical Descriptions: Once we've gathered the requirements, we can feed them to the next step of the software design process. This is where we provide short, accurate descriptions of our systems functionality from the user's perspective. One way of documenting our systems features is through use cases. The use case needs a title, something like create new trip, added expense, or convert currencies. Note that each use case should represent a distinct functionality. Next, we define the actor who's using this functionality. We call it an actor, since it can represent a user who's interacting with the app, but also a non-human entity like another system. Then we describe the details of this specific use case. This is called the scenario. Here, we should write one or more sentences that explain what and how the system works in this particular case. Here's an example. Create a new trip. This is the title of our use case. The actor is that the user of the mobile app. The user can initiate the creation of a new trip from the main screen. The Tidal is mandatory. All the other settings are optional. Optionally, the user can write a short description and set the start and end date for the trip. The app assigns a default home currency based on the phone settings. Users can override the default home currency with any of the supported currencies. The app allows setting the budget for the trip. The setting is optional. Also, the user can assign a custom thumbnail to a trip. Finally, the user conceived the trip or cancel the trip creation process. You can write this as a paragraph or as a bulleted list. The format doesn't really matter, but it's important to avoid technical terms. Again, this description should be understood by all stakeholders, including the end-users. The format of the use case document may vary from company to company. Some may include additional details, but that won't change the essence of it. The use case document aims to provide a clear and human-friendly description, what a specific part of a software does, and how the actors interact with it. And it is a textual description. We talk about the use case diagrams later. User stories are another common way of describing certain features or parts of our application. User stories are shorter than use-case descriptions, usually only one to two sentences long. They typically follow this format as a type of user I want. And you provide some goal so that some reason, examples. As a user, I want to add notes to my expenses so that I can identify them later on. As a power user, I want to retrieve the app's database file so that I can inspect it on any computer. If you can't describe a user story in one or two sentences, you may need to split it into multiple, smaller user stories. These larger user stories are known as epics. Epics cover a bigger chunk of functionality, like in the following case. As a traveler, I want to track my expenses while abroad so that I don't exceed my budget. This epic could be split into many user stories, including these. As a user, I want to create new trips so that I can track each of my trips individually. As a business traveler, I want to tag my business trips so that I can separate them from my private travelers. User stories are often written on sticky notes or index cards. You will see them arranged on wass or tables during meetings and discussions. Unlike use case descriptions, user stories don't capture the feature details. They serve as discussion starters. Instead, user stories are about communication and you will usually see them in Agile projects. Whereas use his descriptions are preferable when employing waterfall methodologies. 18. 4.4 Why Do We Need a Common Descriptive Language?: The first two steps of the object-oriented analysis don't require any special tool or design language. We only need text editing software. Even a piece of paper or a whiteboard would be sufficient to collect the requirements and jot down the use cases or user stories. The next steps require us to depict the classes that form our system, how they behave, and what attributes they need. We also need to visualize how the objects interact with each other. The development community faced this very same problem. The lack of a commonly accepted design language led to the proliferation of different non-standard approaches. We could also try to come up with a way to draw everything from classes to object interactions. But luckily, we don't have to. The Unified Modelling Language is a common design language that was released in 1997. Uml provides a set of standard diagram types that can be used to describe both the structure and the behavior of software systems. We'll dig deeper into UML in the upcoming section. 19. 5.1 What's UML?: Understanding a software system just by looking at its source code can be very time-consuming. And communicating ideas about software design or business processes is even more challenging if there is no commonly accepted way to do it. The Unified Modelling Language in short, UML, was introduced to solve this problem. Uml is not a textual programming language, but rather a graphical notation consisting of diagrams that let us model software systems. We can use these diagrams to describe the objects that form a system, their interactions. Uml has many diagram types. We'll be discussing the most common ones. The use case diagram describes the functional model of a system. That is, the functionality of a system from the user's point of view. To describe the structure of a system, UML provides structural diagrams. We'll talk about the class diagram, which can be used to describe the structure of a system in terms of objects, attributes, operations, and relations. Uml lets us model dynamic behavior to the behavior or diagrams describe the systems functionality focusing on what happens and the interactions between objects. We'll talk about the actual diagram shortly. The best part about UML is that it's independent of any particular programming language. We can start coding an object-oriented software based on UML diagrams. If those diagrams are detailed enough, they can be converted to source code. Now, let's see some real life examples using UML. Software developers often find themselves in situations where the solution to a specific problem is not trivial or there are several different ways to tackle the problem. It may be tempting to open up your ID and just start coding. The next thing you know, ours have disappeared and you are desperately searching stack overflow for the answer. However, it's hard to find a solution if we couldn't first formulate the question, we need to figure out what to implement before writing a single line of code. That when UML comes in handy, whenever something is unclear, we can quickly sketch a few diagrams to represent a specific part of a software or new functionality. The benefits of this approach at twofold. First, by thinking about classes, objects, and interactions, we gain a deeper understanding of what should be implemented without being distracted by crashing IDs or strange compiler error messages. Secondly, a design helps us communicate our ideas with other developers effectively. We can use UML diagrams as a starting point for discussions and improvements without having to delve into source code. Although checking the actual code is useful in many situations, it will often distract us from answering the real questions and turned the design discussion into a code inspection. Another frequent use of UML is drawing diagrams from existing code. This technique is called Reverse Engineering, and it helps uncover the dirty little secrets of undocumented software systems. We can use UML to create a detailed blueprint of a system. Detailed UML blueprints are usually required for software developed using a waterfall approach and less frequently for Agile projects. Although UML is excellent at modelling object-oriented systems, the fact that its platform and programming language independent make it averse of the modeling tool that's not limited to software projects. Uml has been used in multidisciplinary areas, including scientific research, transportation, banking, and defense. 20. 5.2 Use Case Diagrams: Let's start with a use case diagram. It's one of the simplest UML diagrams. It's purpose is to visualize the functional requirements of the system. Use case diagrams show groups of related use cases. Sometimes they may include all the use cases. The result is an overview of the system that may include several written use cases. You will rarely create use case diagrams for a single use case description. To represent the use case, we draw an oval in the middle of the screen and put the title of the use case in it. Create a trip entry, edit trip export app database. These are examples of use cases from our travel expense app mentioned before. We'll stick figures to represent the actors. As you may recall, actors are human beings or other systems that may interact with our system. We draw the stick person to the left or the right of the diagram. The actor's name goes below the stick figure. We usually draw the primary actors on the left side and the secondary ones on the right side of the use case diagram. Next, we draw lines to represent the interaction between an actor and a use case. A mobile user can create or edit a trip entry, but cannot export the app's database. The power user can perform all these actions. We need to visualize our system's boundaries if it interacts with other systems. For that, we draw a frame around all use cases and actors that belong to a given system. Let's say that we're relying on an external cloud-based storage. I'll represent this external system as a separate actor. On the right side. I even change these visual representation to show that it's not a human actor. Most tools allow you to do that. The creator trip entry and the edit trip use cases would rely on the Cloud to backup their data. So I connect these use cases with the external system. The frame makes it obvious where our apps boundaries end. Use case diagrams provide a clear way to communicate the high level features and the scope of the system. You can quickly tell what our system does just by looking at this use case diagram. The system lets users create new trips and edit existing ones. Power users can even export the database. The app relies on an external cloud system to store is data, such as simple diagram makes it clear what the system does and doesn't do. A customer or a user can easily see if needed features are missing. The absence of use cases shows what the system doesn't do. The UML use case diagram includes other artifacts and relationships between use cases. We're going to ignore them as they tend to over-complicate are designed and the benefits are questionable. You can't go wrong if you focus on the actors, the use cases, and their interactions, you will be able to easily create your own use case diagrams and communicate your ideas in a clear and concise way. Use case diagrams provide an easy to understand overview of the features of our system. Now, keep in mind that use case diagrams are not a replacement for written use case descriptions. Use case descriptions include more information to ensure that we don't miss any important details or requirements. 21. 5.2.1. Use Case Diagrams: Challenge: As you just saw, use cases can help you describe the essential functional requirements. Let's put what you've learned into action by solving a challenge, your goal is to draw use case diagram that provides an overview of an elevator system. Before drawing the diagrams, tried to answer the following questions. What actors interact with an elevator? And what are the main functions of an elevator? Here's a simplified elevator control panel you can use as a reference for this exercise. When defining the actors and use cases, take into account that elevators require regular maintenance and repair. Now, hit pause and try to come up with your elevator use case diagram. In the next video, I'll show you my solution. But I suggest you watch it only after you're done or if you get stuck. Good luck. 22. 5.2.2 Use Case Diagrams: Solution: Welcome back. Now, let me show you how I would approach this challenge. To create our use case diagram, we need to identify the system, the actors, and use cases. Our system is the elevator. Let's add it by dragging a use case subject onto the canvas. I'm going to call it elevator. That was easy. Now, who's interacting with the elevator? An elevator is designed to carry people. And I can represent a person as a single actor called user. What can the user do with the elevator? Let's have a look at the elevator control panels. Obviously, we can call the elevator. I'll add this use case to our diagram and drawn association between the user and the use case. After entering the elevator, you select a floor. That's the second use case. And let's connect it with the actor. The elevator takes us to the selected floor. This action can be described as ride the elevator. There are some additional buttons on the control panel. You can open or close the doors. I'll add a single use case for this, say operators doors. You can also push it the red bell and trigger the emergency alarm. I will add this use case 2. So far so good, But we're not done yet. Elevators are essential tools that need to run safely and reliably. Elevator mechanics are skilled technicians who are trained to install, maintain, and repair them. I add a new actor called technician, and some special use cases. Inspect elevator, service, elevator, and repair elevator. On top of these, that technician can also call the elevator, select the floor and so on. However, the average user should not perform any of the maintenance or repair activities. These use cases are exclusive to the technician role. So this is my solution. Did you come up with something similar? To summarize, use cases can help us understand the essential functional requirements. They provide a quick external overview of the system. Make sure to keep your use case diagram simple and focus on the actors and the textual use case descriptions. 23. 5.3 Class Diagrams: without any doubt. Class diagrams are the most frequently used. Um, a diagram types. After identifying the entities that form our system, we start creating class diagrams for each of them. The class is represented on the class diagram as a rectangle with three compartments. First, we need to list the classes name when naming our classes. We must a dear to some rules, these rules are known as naming conventions. A glass name should be a noun in the singular, and it needs to start with an uppercase letter. For example, trip. If the name consists of multiple words, we need to uppercase each word like in this example offline. Persistence manager. This style is called Upper Camel case, which is camera case with the first letter capitalized Camel cases. The practice of starting each word in a compound word or sentence with a capital. Why do we need rules? Why can't we just use any character sequence to name our classes? Well, we could do that. Yet a naming convention lets us focus on important issues. Instead of arguing over syntax and names with the commonly accepted set of rules, we can easily read the source code rhythm by other developers, even if they're from another company, country or continent. Standards are useful. All right, so our class name should be a noun in Upper Camel case. Let's feel the other two compartments to the next one. Least. The attributes. The attribute names should be concise, and they should follow the lower camel case. Former that is, with the first letter lower case and the first letters of subsequent words. In uppercase. A Trip has a name. It has a creation date. Let's call it created at It needs to have a home currency. The started starts at and on end, date and set. It's also useful to specify the type of the attributes. We can do that by writing the data type after the attributes name separated by colons. So here's our trip class with the attribute names and types. Now the data types need to be adjusted to whatever programming language you're using. This example makes perfect sense in Swift for objective. See, you may want to use different types, like in a string instead of string and in his date for dates. But even if we leave it as it is, nobody will have issues understanding that you referred to a string or a date or an integer . Next comes the operations compartment. This is where released the glasses. Methods method names should be words in lower camel case. We can also specify method arguments. The parameters appear within the parentheses as name data type pairs to show that the method returns something. We add a column after the closing parentheses followed by the return type. And we can also have methods that have arguments and a return type. Get entries takes two arguments called from date and and eight both of type date. The method returns our list of entries. This list could contain multiple values or just a single value, or it could even be empty. We don't specify this in our class diagram. 24. 5.4 Visibility: Public, Private, Protected, Package: Now let's talk about visibility. Um, A lets US control who can access the attributes and the methods of our classes. We have the following visibility levels in um el Plus means public visibility, a glass method or attribute mark. This public can be used by code outside of the object, minus the notes. Private access, private attributes and methods can only be used within the class that defines them. Elements marked this private can't be accessed directly from other classes. Um, A uses hash mark to market element as protected. Protected visibility means that only child classes and the defining class will be able to access that attribute or method. Tilde denotes package visibility, which makes sense in some programming languages. That letters group are called in tow logical units and provide a name space for this group . Using package visibility, we make our elements available within its enclosing package. Um, A provides these visibility tags, but it's up to us to adapt it to the language we're using. Now. There's one rule that's common for all object oriented languages. You should only expose as much as needed and hide everything s class. Attributes will usually have private or protected access. We should provide Public Stater's and gathers instead of allowing everybody toe access our classes data. This lets us control what the colors do with our classes. Attributes. In our trip class, we could make the name attributes. Public collars could set and retrieve it, which seems to work as expected. But what if we need to make sure that a trips name is never shorter than, say, three characters? There's no way to enforce this requirement. Another example. The trip start date needs to be earlier than its mandate, Yet callers can freely set any start or end it. I'm going to change the visibility of are these attributes to private Now we can access them exclusively from within the classes own methods. After these change, other objects can't set or reduce these attributes. They are, well, private. Toe the trip class awesome. But then how do we set, retrieve or modify them? Here's a solution. I provide public gathers and centers for each of these attributes. Get name SAT name gets started, set started, get indeed set indeed, and now we can check whether the name is at least three characters long by validating the name parameter in the satiny method. If it's shorter, we just print a warning message and return. Also, we can know validate the start and the end date in the corresponding Sattar's. We are now in full control of our classes. Internal data centers. Let us check the input argument and gathers. Allow us to modify the value before returning it. For example, we could return a date in the user's time zone. So far, we've seen how to represent a single class class diagrams. Let us also show the relationships with me and the classes in our system. We talk about relationships next. 25. 5.5 Associations: the next logical step after identifying the key classes in our system is figuring out the relationships between them, use cases or use our stories will happens during this process. He is one of the functional requirements off the travel expense app. We have a trip and an expanse glass. Each trip will include its travel expenses, so there needs to be some relationship between the trip and the expanse glass. To express this relationship, we draw a solid line between these classes. This line represents an association. The association tells us that the classes referred to each other. We can be more specific here. The trip class needs to know about its expenses. But should the expense class also know about the trip class? We've already talked about the drawbacks of tightly coupled systems. Tight coupling is something that you should definitely try to avoid. Let me illustrate the issue it causes. The three prefers to the expanse class. That's fine, since the trip can have expenses associated with it. Now, what happens if also the expense refers to the trip class? Because of this reference, if we try to use the expense class in other parts of the system would need to also bring the three place with it. This doesn't make sense, as we should be able to use an expanse without the trip. UML lets us express directed associations by drawing a solid line that ends with an open arrowhead. We showed that only one of the classes refers to the other one. The arrow points to the class that's referred to by the other class. In our current example, the association is bi directional. Let's change it to a directed association. Now it shows that the expenses associated with the trip, but the expense class doesn't know anything about the trip glass. A trip will usually have multiple expanses. We can represent the multiplicity of associated objects as follows. Asterisk. A trip can have zero or more expanses. One a trip must have exactly one home currency, 0 to 1. A trip may or may not have a single note. Associations can show Multiplicity is at both ends of the line. The default multiplicity is one. So if there is no multiplicity is shown, you can safely assume it's one. We can also display the name of the class. Property for the given Association Association isn't the only kind of relationship we can have between classes. Next, we're going to talk about generalization 26. 5.6 Generalization: in Um el. We use generalization to express that one model element is based on another model element. Generalization is represented as a solid line with a hollow air ahead that points to the parent. Let's say that we need a special treat class for our business trips Business trip would inherit from the trip class, and this is how we represented in you, Emma. Because business Trip inherits everything from its parent, we must only specify the attributes and operations that are specific to the child. A parent can have multiple Children, and we can also have tried glasses that inherit from different parents. Some programming languages support multiple inheritance c++ PERL python, just to name a few. Many modern programming languages only allow single inheritance that is inheriting from one parent class. Single inheritance reduces the complexity and avoid the ambiguity that comes with multiple inheritance. Some argue that multiple inheritance has more benefits than drawbacks. However, it's certainly easier to make mistakes when he was in multiple inheritance. Um, er doesn't restrict generalization. Two classes. It can also be was in news case or component diagrams. This lets us indicate that a child element receives its parents, attributes, operations and relationships 27. 5.7 Visibility: Public, Private, Protected, Package: we talk about the dependence relationship if changes in one of the classes may cost changes to the other. In um, El Dependency is represented as a dashed line that ends with an open arrowhead. The arrow points with the dependency a dependency. It's a directed relationship. Dependency is often confused with association. But there's a big difference. Association indicates. Very CREss has an attribute of the other classes type, whereas dependency is usually created when the class receives a reference to the other class. For instance, through a member function, parameter aggregation represents apart with relationship and is drawn as a solid land with a hollow diamond. At the owners end. This relationship is considered redundant because it expresses the same thing as the association. So these two diagrams are equivalent. Composition is a stronger form of association. It shows that the parts leave and die with the whole. In other words, composition implies ownership. When the owning object is destroyed, the contained objects will be destroyed, too. The composition is represented as a field diamond on the owners and connected with a solid line with the contained class. The expenses of a trip can't exist without the trip If we delete the trip, it's expenses are going to be removed to realization indicates that a class implements the behavior specified by another model element. It is represented as a hollow triangle on the interface and connected with dash lines. With the implementer classes, we could specify an abstract trip type to ensure that our current and upcoming trip glasses provide a common set of methods. This is a useful feature that allows polymorphic behavior. Here's a quick summary of the relationships and their graphical representation. Generalisation, which is an easy relationship association aggregation that the note has a relationships composition, the part of relationship dependency used them, classes reference each other and realization used to indicate that a class implements the behaviour defined by a model element. 28. 5.8 Sequence Diagrams: use case and class diagrams are static diagrams. They are great at representing the structure of our system. But what if we need to show how the objects interact with each other? When are objects created and for how long are they around? Static diagrams can't answer these questions. Um ER provides dynamic diagrams to represent how objects communicate with each other. The most common dynamic diagram is the sequence diagram. We used a sequence diagram to describe the flow of logic. In one particular scenario, a sequence diagrams starts by drawing boxes at the top of the page. Each box represents an object. Since these are objects, we name them differently. The trip instead of trip and un expanse rather than expanse. We can also display the type after the instances name separated by a Kahlan. This may be helpful. In some cases, the lifeline of an object is represented by the dotted lines beneath each box. The San shows the time the instance, exist during the scenario. The sequence diagram also lets us show the messages sent from one object with the other. A message is basically a method call. Now let me illustrate the various messages in the practical example I'll be using started Wimal Ah, um, a diagramming software that can be downloaded for free from star um a dot io. Let's assume that we have a persistence manager object. This object is responsible for storing entities in the apse local database. The persistence manager needs to create and store a trip entity. Instance. First I add the trip entity Object. The persistence manager instance sends a create message to instance, she ate a trip entity object. The create message is represented as a dashed line with a stick arrowhead. Next, the persistence manager sends a regular message toe the already created trip entity. This message corresponds to calling the ad note method on the trip entity. Instance a regular messages shown as a solid line with the Field Arrowhead. We can also add parameters to our messages if we wish. Although we could display the return message, only do it if it's important. Return messages are implicit for synchronous messages so we don't have to display them. Asynchronous messages are drawn as solid lines with a stick arrowhead. The controller objects sends an easing save message toe the persistence manager. These corporations are slow, so inserting a new record into the database is a perfect candidate for on a sing call. When an object sends on a sing message, it doesn't need to wait for a response. The asynchronous call gets executed in the background, and it returns once it completes. Unlike synchronous cause, it doesn't block the caller. Asynchronous behavior stands at the core of modern software systems. They improve responsiveness on multi core processors and provide better user experience because lengthy operations won't block the user interface, so you'll probably draw facing messages a lot. The issue is that the difference between regular and facing messages is very subtle. Stick Arrowhead instead of Field Arrowhead. To avoid misunderstandings, you can add an extra note to make it visible. It's on facing message. We also have South messages. These represent the method calling another method of the same object. An object can also send the delete message to another object. The persistence manager sends a delete message toe the trip entity. Instance. The trip entity gets destroyed and its life land gets terminated by a cross symbol sequence . Diagrams should provide an overview of what's going on in a given scenario. We don't try to represent all the method cause precisely. Instead, we focus on the most relevant parts sequence. Diagrams help us in clarifying the interactions between objects in a specific scenario. By getting more profound insights into the inner workings of our objects, we may need to refine their behavior or even at new classes, or establish new relationships between our classes. And that's perfectly fine. The process of designing the software system is all about finding out what's missing, what needs to be enhanced or changed. 29. 5.9 Activity Diagrams: activity. Diagrams can be used to describe work flows. The actions are represented by nodes with statin activity diagram, with an initial note drawn as a small feared circle. We can then transition to the next node. The transition is called flow, and it's shown as a line that ends with an open arrowhead. The arrow points to the direction of the logic flow from one action toe. The other activity diagrams can also express conditional logic. We model a decision note. As a diamond, it has a single incoming flow and two or more outbound flows. Each outbound flow has a guard, a Boolean condition placed inside square brackets. The guards need to be mutually exclusive. Whenever we reach a decision, we can choose only one of the outbound flows. After a decision, the flows can be march dosing, um, objectivity. The march has multiple input flows and the single output flow activity. Diagrams support paddle behavior to express, conquer and flows. We use a fork drawn as a thick horizontal line. A fork has one incoming flow and several outgoing conquering flows. We need to synchronize the tasks that execute concurrently. For example, we can't display the image while it's being read from the local persistence or download it from the server, a joint represented synchronization point. The final note marks the end of the workflow. The following activity diagram describes a simplified version of the trip creation process . We begin with the initial node. The user decides to create a new trip. Next, he's asked to type the trips name. Now the APP needs to check whether a trip with the same name already exists. If it does, we prompt the user to enter a new name or cancer. The three creation process. If he decides to cancel the flow, we end the activity. Otherwise, we validate the name again. If the trip name isn't taken, we let the user feel the remaining trip data. Finally, the user his deceived button. We may also want to let him cancel the process here. Now I use a fork to show that we perform some actions in peril. Storing the new trip into the local persistence and uploading it to the Cloud Server happened concurrently. If both actions succeed, we inform the user about the successful trip creation and we're done. The activity diagram is a useful technique to represent behavioral logic. I wouldn't recommend it when working with non technical people, though 30. 5.10 Statechart Diagrams: the state machine or stay char diagram models. How one object transitions from one state to another. Over its lifetime, it describes. The state changes oven object in response to certain events. The state is a condition in which an object exists. Think of objects states like new. Pending changes or completed, the states can change when some event gets triggered. The pending changes state transitions to saved after a successful save event and the safe state will change toe the final terminated state if the object is deleted. The state machine diagram starts with an initial state. This is not a real state, but rather the entry point. States are drawn as rectangles with rounded corners with the state's name. The transitions from one state to another are shown as lines that end in an open arrow. Each transition can be labeled with an event name and the guard. The God is a Boolean condition that needs to be true for the state change to occur, let's assume that pending changes can only be saved. If the device is connected to the Internet, we can represent conditional logic in states are diagrams as follows. The final states shows that the state machine is completed, and it also implies the deletion of the object. You stay char diagrams to describe the object states of a system while identifying the events responsible for the state changes. 31. 6.1 Case Study: Designing a Note-Taking App from Scratch - Collecting the Requirements: in this lecture, I'm going to illustrate the requirements collection phase through a real example. Let's start by thinking about the features of a note taking application. First, we're going to be creating an editing, text based notes, but we don't want to create the next boring note taking app. So let's get creative and at some interesting features. How about adding photos to our notes and capturing can drawn sketches would be a cool addition to privacy has become increasingly important. We should allow the storing of sensitive notes automatic sinking to Dropbox, iCloud or Google Drive. Sure, many users will find that a useful feature. Now that we have some ideas floating around, we can come up with the first draft of our distilled requirements. No taking AP functional requirements. We need to build a note taking APP. Users can create an added tax based notes. The note may also include images or hand drawn sketches. Sensitive notes can be protected from prying eyes. Using a password, the APP automatically upload changes to pre configure servers. We should support all major platforms Dropbox, iCloud and Google Drive. Next, let's talk about the nonfunctional requirements. Which platform should be target. Let's release our APP for IOS first with support I was 10 and newer versions. The APP needs to run on the iPhone and the iPad as well. We're greater dedicated support website and will also include the link in the description. And it's about Paige. Now that we have collected the requirements, we can proceed to the next step. We're going to map these requirements toe technical descriptions. 32. 6.2 Creating User Stories: now that we've gathered, the requirements will be writing user stories. So let's get started these out of the functional requirements we need to build a note taking APP. Users can create and added text based notes. The note may also include images or hand drawn sketches. Saturday's knows can be protected from prying eyes using a password. The APP automatically uploads changes to pre configure servers. We should support our major platforms Dropbox, iCloud and Google Drive. We identified three major topics here. One note creation and editing to privacy protecting user data and three sinking to cloud servers. These are all big chunks of functionality that can't be described through single user stories. Thus, I'm going to create an epic for each. As you may recall, an epic consists of multiple user stories that describe common functionality, epic number one, note creation and editing. As a user, I want to create and edit notes so that I can quickly jot down my thoughts. As a user, I want to attach for those toe a note so that I can keep my memories in one place. As a user, I want to add an written sketches so that I can insert funny tools into my notes. Epic number two Privacy. As a user, I want to create private notes so that only I can access them. As a user. I want to protect my sensitive notes with the password epic number three Sinking to Cloud servers. As a user, I want to sink my notes across my IOS devices so that my data is up to date on all of them . As a user, I want my notes automatically uploaded to cloud servers Dropbox, Google Drive or iCloud so that I have a back up of all my data. These user stories are technical descriptions that serve as a starting point for our use case diagrams and up next, I'm going to show how we might go ahead and map these use our stories to actually use case diagrams. 33. 6.3 Diagraming the Main Use Cases: in this lecture, we're going to represent our user stories as use case diagrams. Let's start with the first epic note creation and editing. As a user, I want to create and added notes so that I can quickly jot down my thoughts. As a user, I want to attach for those toe a note so that I can keep my memories in one place. As a user, I want to add an written sketches so that I can insert funny tunes into my notes. I'll continue in start. Um er I ever use case diagram. Now who's the actor? The actor is the user of this app. Next I ed the use cases. Create note and added note. We also need on attach photo and at hand written sketches. Case now, these are not standalone use cases. We can't attach a photo or add a hand written sketch without creating or editing a note. Thus, I represent them as included in the create note and edit note news cases. The second epic is about privacy. As a user, I want to create private notes so that only I can accept them As a user, I want to protect my sensitive notes with a password. Again, we need a nectar. The creating private notes is a special case of note creation. We can represent the create private note as an extension of the regular create note use case. We need to protect sensitive notes with a password, so I create a protect with password use case for it. The souse case should be included in the Create private note use case, so I dry it using on include relationship. And here's the third epic Sinking to Cloud servers. As a user, I want to sink my notes across my IOS devices so that my data is up to date on all of them . As a user, I want my nose automatically uploaded to cloud servers Dropbox, Google Drive or iCloud so that I have a back up of all my data. Again, we need a nectar. This epic is about synchronizing data with a server. The server is another actor, the non human one I represented on the right side of the diagram using the special four months. Now let's determine the use cases. So whenever we create or modify a note, it needs to be sync with the server That's an oversimplification, but it illustrates what needs to happen in this scenario. As you may recall, use case diagrams are means to share our ideas with nontechnical people, so try to keep it simple. Next, we get into more technical details as well start to identify our classes. 34. 6.4 Modeling the Classes and the Relationships: Let's agree. The stat extractor of our system will identify the main classes, and the relationships between them are. APP is about taking notes, so we'll need a class that represents a note. A note has a text, so I add a private attribute called Text of type string. As you may recall, we should not expose class properties. Hence, text is private. What has the window? Let's take a look at the use case diagrams we've put together. We also need on attach photo and at hand written sketch use case. A note needs toe. Have an attribute for the photos and one for the hand written. Sketches, as you might have observed, were using the plural form photos and sketches. There is a note may have many photos and hand drawn sketches attached to it, so I'll make these attributes of least type. The note class needs some methods. Set text to set the notes, text and get text to retrieve the text, add image toe, attach a new image and get images to retrieve all images of a note and add sketch and retrieve our sketches to get the hand drawn. Sketches of a note. The photos attributes is a list of image type. I introduce an image class which can later be changed toe on existing type. For example, in Iowa's that would be you image, but that's not important. The point is to identify the potential classes that play a role in our system. Similarly, we need a list of sketches the sketch class represents are hand drawn sketches. We don't know anything yet about the underlying format for the image and the sketch class, but that's fine. We need to abstract things first and narratively refined. Our design at the end we may store are hand drawn sketches, either as an image or some vector format like Pdf again, we should not go into such details at this stage, or we may easily get stuck. This phenomenon is well known, and it even has a name analysis. Paralysis start with broad strokes instead of overthinking and spending too much time on figuring out the details right away. Then try to get more specific as you understand more. Now let's think about the relationships between thes classes. Is thereon association between the note and the image class, or rather, a dependency. The note class has an attribute that refers to the image and the sketch class. So is it an association? Yes, it is. But let's analyze it further. What happens when, with a little note object with its images and sketches, they will be destroyed, too. It doesn't make sense to keep them. If the user decides to remove the note, that means that the images and the sketches leave and die with the note Object. As you may recall, this is the part of relationship called composition. Now an image doesn't need to know about the note. Neither does the sketch. So these should be directed relationships. Based on the second epic, We need a specialized note that holds sensitive data. This no chairs most of the attributes and behavior associated with the note class, so this looks like a perfect candidate for inheritance. Secure note inherits from the note class. In addition to the inherited attributes, it has a property called passport hash. Storing the best word is unsecure, so instead of storing the password we store it's hash value, the hair she has generated using one way hashing algorithm from the password. The password can be reconstructed from its hash value for the hashing algorithm, I'm going to define the crypto class. It provides a public hash method that takes a string as input and returns its hash value. Vasic, you note, is going to rely on the crypto utility class toe. Create the password hash. I indicate this as a dependency between the secure note and the crypto class. Next, we need the class that's responsible for storing the notes and their associated data in the local persistence. We don't want to be too specific at this point, as we haven't defined yet what local persistence means. It could be the fire system or a sequel I database. Maybe we'll use core data. That's not important at this point, so we'll use abstraction. Instead of specifying a concrete file or database manager, I'm going to create an interface that defines a couple of methods. Let's call it local persistence. It's an interface. There is, it declares, the methods signatures that need to be implemented, but it provides no functionality. The implementation classes will be responsible for implementing these methods. Look up our systems, declares the following interface. Got notes, save update and delete note. Let's say that we decide to store our notes in the file system. The fire Manager class implements the methods declared in local persistence. I use the realization relationship to show that for the cloud sinking feature, we need a class that takes care of all the networking related operations. Network controllers are usually more complex, but I keep it simple for this example. I only add the following methods. Create note that notes, delete and update Note. Networking is slow, So these are all asynchronous operations by now. You've probably got an idea of how class diagrams are created. Now that we mapped the stead extractor of our system, we can start analyzing its behavior. 35. 6.5 Describing the Flow of Note Creation using Sequence Diagrams: I'm going to walk you through the creation of the sequence diagram for one specific scenario, adding a note will be focusing on the flow of note creation, which objects are involved and what messages are sent between them. The user can initiate the note creation by pressing a button on the applications user interface, so we need the view. Instance First that represents the button. The button receives the user input and triggers an event that's intercepted by a controller . Object. Having separate view and controller objects stands at the core of a van. Known architectural design pattern called model view controller. The view displaced data and receives user input. The controller triggers actions based on events received from its views and processes the data to be displayed In our scenario, the controller triggers the creation of a new note. Instance will use a create message rather than a regular one. The note object gets created. Next. The user fears the nose details and presses the save button. This would trigger to actions saving to the local persistence and uploading the new note to the cloud. Local persistence is managed by the fire manager object. I involve the same note method file operations are slow. Thus, I involved the same method, a synchronously. To avoid misunderstandings, I mark the message explicitly as a sink for the upload part. We need a net for controller. Instance. Create note gets executed in the background. The saving to local persistence and uploading the new note to the cloud are asynchronous, so they return instantly without blocking the caller. Eventually, they return to signal either success or failure. We can provide more details by adding further objects and messages as needed. But the sequence diagram has us a lot already about the objects and how they interact in the milk rations scenario. 36. 6.6. Modeling the States of a Note Object: Let's take a closer look at the possible states of a note object. A note object is created, saved, and that's it, right? Well, not quite. Let's start analyzing of the possible states and what could go wrong. We'll soon realized that we need to represent more states than we originally assumed. The note objects states are diagram starts with an initial state. When we create a note, it's in the new state. This condition is triggered by the creation event. After a new notice created, the user needs to fill in some details. At the end of this process, the note will have unsaved changes. We need the state to express this condition now. The user can save the note, but he may also decide to cancer. The process, which means that our state machine reached its final state saving a note, imply storing it in the local persistence and uploading it to the cloud. These are two actions that could possibly fail if none of them succeeds. The state of our note object turns back to unsafe changes. If both succeed with fish toe, the persistent and uploaded state storing a new note in the fire system will usually complete without issues. However, uploading data to a server could fail for various reasons. The Persisted state shows that only storing the note locally was successful. The user can retry the uploading action, which changes the state of the note object toe upload pending. If this attempt also fails, we go back to the persistent state. Otherwise, the object states, which is toe persisted and applauded. Our note object was successfully created, saved toe the local persistence and uploaded to a cloud server. That's the less state so we can complete our state machine by transitioning to the final state. When creating states are diagrams, it's important to always have a way to exit the state after its entered. The only exceptions are the initial and the final states. Let's say that I want to express the archive state. The note object should treat toe that state if the user quits the APP while the notice in the unsaved changes state when the user starts the app next time the note remains stuck in these archives. The state. There's no transition toe any other state. The situation is called deadlock, and it's one of the biggest issues you can encounter with state machines to solve the problem. I add a transition toe. The unsaved changes state. This transition is triggered by the APP started event. So this is a state diagram for the note object. We definitely got more states than we originally assumed. 37. Goodbye!: congrats. You've reached the end of the scores. You have hopefully found it useful. By now, you've probably become familiar with the fundamental object oriented design concepts. Practice makes the master. So try to put the techniques describes in this course into practice. You'll notice that designing software systems gets easier over time. Explore different alternatives when sketching your designs. Although there are some best practices, feel free to adapt them to your needs and, most importantly, don't get lost in the details. Start with the simpler draft design you can gradually refined and enhanced your diagrams as you understand more about the system you're building. And one more thing I love to hear from you. Feel free to message me, and if you found this course useful, please leave a review. Orating. Thanks for watching. 38. Q&A - How to Create Associations in Use Case Diagrams using StarUML: Hi there. I've had a question in the Q and A section the students could not great associations in the use case diagram. So here's a quick video showing how to do that. Let's make sure that we create a use case diagram. First, I'm going to create the actor mobile user. Next, I add the Create Trip Entry use case and next, the Edit Tributes case. And finally, I'm going to create the actor Power User. And now the question is how to create the associations with being the actors and the use cases. First of all, don't select anything. And now let's click Association in the to box. I'm gonna left click on the actor, keep the left button down, and while it's pressed, I drag the association line to the use case we wanna connected to, and I repeated for every actor and use case this should work in. Sorry, Emma 2.8 point one, and also in order and upcoming versions. So that's it. It's really that easy to create use case diagrams using study women. Thanks for watching