[MUSIC] Hello again and welcome to the second module. In the first module, we discussed the different ways that software architecture can be represented visually. Now we will get into a variety of different software architectures. These architectures can be used separately in their pure forms or put together to guide the design of a working software system. After completing this module, you'll be knowledgeable in important software architectures, their key characteristics, and how they're used in practice. We hope you're as excited as us. It should come as no surprise that the programming paradigm of the language used to implement the system will affect the architectural style of that system. Each programming paradigm has its own set of constructs and their use will shape the system you create. There are many different styles of language-based architecture systems. In this lesson, we will explore the object-oriented architectural style, which results from the object-oriented programming paradigm. When you're choosing to develop a project using an object-oriented language, such as Java or C++, you're not simply choosing a language. Object-oriented principles, constructs, and design problems are all part of the whole deal. Before we move on, let's briefly recap the object-oriented principles that are available to you. First, there's abstraction. With abstraction, you can simplify a concept by ignoring unimportant details. Next up is encapsulation. Encapsulation allows you to bundle data and functions into a self-contained object. So that other objects can interact with it through an exposed interface. Also, let's recall decomposition, which allows you to break up a whole problem into smaller, distinct parts. And lastly, generalization allows you to factor out conceptual commonalities. Also at your disposal are object-oriented design patterns. Object-oriented design patterns fall into creational, structural, and behavioral categories. Creational patterns guide you in creating new objects. Structural patterns describe the relationships between objects and the interactions between classes and subclasses. And behavioral patterns focus on how objects perform work individually and how they can work as a group to accomplish something. Together, elements like these will lead to an object-oriented architectural style for the system. The object-oriented architectural style is focused on the data. When presented with a system to model, you may begin by looking at the different kinds of data handled by the system to see how the system can be broken down into abstract data types. An abstract data type can be represented as a class that you define to organize data attributes in a meaningful way, so that related attributes are grouped together, along with their associated methods. An encapsulation restricts access to the data and dictates what can be done with it. Object-oriented refers to a system composed of objects, where each object is an instance of a class. In other words, the type of each object is its class. Objects may interact with each other through the use of their methods. The object-oriented paradigm allows for inheritance among abstract data types. This means that one abstract type can be declared an extension of another type. These classes themselves form a language-based architecture that arises from basic object oriented principles. The classes within the system will determine the overall structure of the system. Now lets consider how an automatic pet feeder would be implemented using an object-oriented approach. Our goal is to create classes that accurately and succinctly model the entities involved in the problem. To do this, you must first take stock of the data and information flow that is present in the system so that we can identify classes within this system. The objects in this system are the pets and the food dispenser. The food dispenser device consists of a pet food storage container to hold the kibble. The bottom of this container may be temporarily opened to dispense food to a dish below. The dispenser also includes a light on top that will flash when it's empty. Each pet in the system wears a collar with a unique ID tag. Suppose that when in close proximity to the food dispenser, the pet's collar tag triggers the food dispenser to drop a portion of pet food into the dish. We can model pet and food dispenser objects in the system as abstract data types. The pet class would have attributes for it's collar ID, maximum daily food intake amount, and current food intake amount. The maximum daily food intake amount is a value the pet owner can set that determines the maximum amount of food the pet may consume in a whole day. And the current food intake amount is the amount of food the pet consumed so far that day. The pet class would have a method update or reset its current food intake amount. So each morning, this value would reset to zero. The food dispenser class would have attributes to keep track of which pets are authorized to visit it and how much food is left. The food dispenser class would have a method to dispense the food and a method to flash its light when it runs out of food. Instances of these classes would interact with each other to determine whether or not food should be dispensed when a particular pet visits the dispenser. The overall object-oriented architectural style of the system directly follows from the fact that an object-oriented approach was used in the development. Some problems are well-suited to the object-oriented architectural style. In the example we looked at above, it was relatively easy to identify the classes involved. However, this is not always the case. In a system centered around scientific computation, the identification of classes may result in unnecessary complexity, and in turn, lower performance. As we shall soon see, the object-oriented programming paradigm will not always be the most appropriate solution to a problem. Another design choice may be better suited for the problem at hand.