So, I will talk about design patterns, how you can implement those design patterns with real concrete code and with PHP. I guess most of you are Drupal developers, maybe some symphony developers as well. So this session will help you to know more about object-oriented design. And so you will also learn stuff that you can find in symphony as symphony uses design patterns a lot and I think Drupal does as well. I'm not a Drupal developer, I'm a symphony developer. My name is Hugo. I work for Essential Apps, the company that creates symphony and so I'm one of the major symphony contributors. You can find me on Twitter. My nickname is HMN with double H and this is my cat on the bottom left side of this slide. So this presentation is very code-oriented, as you will see. I will first take maybe 10 minutes to introduce design pattern in theory and then the remaining of the session will be about practicing design patterns. So I will show you four design patterns that I will present you with real world code. So introduction. So what are design patterns? So basically a design pattern is an abstract solution to a common redundant problems. So in software engineering, we always design softwares and when we design softwares, we do things that are recurring from a project to another. And so back in the 70s and 80s, some people decided to find or to invent some patterns on some abstract solutions to fix those problems. So the design patterns were formally, I would say, they were published as a book in the 90s. And as these are abstract solutions, you can implement them with any programming language as long as your programming language supports object-oriented design. So PHP, or Python, or Java, Rails, or Ruby, and whatever. So those patterns, they were mainly invented by four people that we called the Gang of Four. As I said, they created those patterns in the 70s. And there are 23 Gang of Four design patterns. You can find more architectural design patterns now, but those 23s are the default one. And so when they define those patterns, they organize them into three different families. The first family is the creational family patterns, which means all the design patterns that are meant to encapsulate how you create object and how you initialize objects. The second family is the family of structural design patterns. So it's basically the patterns that help you structure the code to make it more flexible and more extensible. And the final one, the behavior patterns family contains the patterns that help, or that define patterns that help your codes or your classes and objects communicate with each other in the way to decouple the objects from each other. So that's the three different families. And so I will show you patterns from the three different families. One creational, two structural, and one behavioral design pattern. So when you use design patterns, you will also leverage some benefits of using them. The first one is communication because every pattern has a name, has a unique name, and every pattern solves a unique problem. So when you know how to implement a pattern and if you know how to recognize them in a code base, then you know basically which problem it solves. And so this helps the communication between software engineers. If every engineer in the team know the patterns, then they will better communicate with the code base. The design patterns also force you to write your code in a way that you make it unit testable. So if you have unit testing tools like PHP unit, if you follow the patterns, your code should be unit testable. The patterns, as I said, they also help to decouple things. You want to have less coupling between your objects. And so this will also ease your maintenance. Because if you want to remove a piece and change it with another piece of code, this should be done without breaking too much things in your code base. And so as I said, the patterns will help you to make your code more extensible and loosely coupled. So these are the main benefits. However, we also have downsides of using design patterns. One of the main downsides is that it's very hard to teach them and also hard to learn design patterns. In my experience, when I started to learn them, I needed several years to master most of them. And I still don't master every 23 design patterns because I don't use all of them in my daily job. But knowing most of them is important. And also, when you want to use a pattern, sometimes it's not very interesting to use them. Sometimes you want to use a pattern because it really solves a problem in your code base and it provides value to your code base. But sometimes it's better to make a quick and dirty patch for your code. So you have to know whether it's valuable for your code base to use a pattern or not. The design pattern also uses object-oriented design. So you need strong knowledge of object-oriented programming. So you need to know about abstraction, encapsulations, interfaces, compositions, and everything. So that's another way of friction to learn design patterns. Anyway, so just before I show you some design pattern codes, I will just focus on this principle. Do you know the solid principle? Some people in the audience, yeah, some? So solid principle is a set of five principles to follow to make your code more unit-testable, more flexible, and better design. The first principle is called single-responsibility principle. This is basically a principle that states that your objects or your classes must be focused on one single responsibility. So one class or one object does one thing and it does it well. This is for preventing your classes to have thousands of lines of codes. If you have a class that has thousands of lines of codes, that means your class does too much things. The second principle is called OCP or open-close principle, which means your code must be open to extension but close to modifications, which basically means you must be able to extend your objects or extend your classes without modifying them, without touching them. So you will see in the design pattern that I will show you that those patterns encourage those practices. The second or the third principle is called LSP or list code substitution principle. It's basically a principle that states that you should be able to remove or to change a dependency of an object with another dependency which has the same contract. So if you have an object A and in the construct method, let's say, of your object A, you can have a dependency of type B. You should be able to swap this dependency B with another dependency of type B prime. And if those two classes respect the same contract, the same interface, then code A should be able to run the same way with either B or B prime dependency. ISP stands for interface segregation principle. It's basically the single responsibility principle but applied to interfaces. So you should make your interfaces short and only focus on what they do. We have an example in symphony, for instance, in the security system where we have an interface called user interface, which describes what a user, an authenticated user is. So you can just implement user interface. But if you want to have a more advanced user interface, which has other actions, then you can also implement advanced user interface. So to avoid having a big user interface in symphony, we just split it in two different interfaces. And the last one is called dependency inversion principle. It's dependency inversion, not dependency injection. I guess that you probably learned a lot of dependency injection during the conference. I think my colleague Nicholas need to talk about that. But dependency inversion means that you should depend on abstraction instead of implementation. So basically when you type into dependency as an argument of a method, for instance, you should use abstract types like abstract classes or interfaces to reduce coupling. So if you do dependency inversion, if you respect this principle, as a consequence, you are also doing dependency injection. So I encourage you to read some more stuff about solid principle because it's very interesting to dig into these coding craftsmanship. So let's start with concrete design patterns and stuff. So I will show you one first design pattern, which is a creational design pattern. As I said, this family of patterns, creational, allows you to encapsulate or to centralize the way you create your objects. So basically instead of using the new keywords to instantiate objects, you will do it in just one place. And then the code that needs to use objects, they will just call some factory objects to get these created objects. So we have different patterns for creating objects. They have different intents and they solve different problems. And the most famous one is probably the singleton, as you probably may know, which is now considered as an anti-pattern because it has lots of downsides, so this is why it strikes on my slide deck. So the one I want to show you is the factory method design pattern because this pattern is probably one of the one that is not the best well-implemented by developers, or it's the one that is the most misunderstood design pattern in this creational list. So basically, the Gengorfer says that the factory method design patterns defines an interface, so an interface can be an interface or an abstract class, for instance, or an abstract type, for creating an object. But it lets subclasses decide which object class to instantiate. So to sum up, that means when you have a factory abstract type, that you have to concretize with a concrete class. The concrete class will be responsible for instantiating one particular type of object, but only one. And this is this factory method design pattern. I will first show you the two approaches that are not the factory, the real factory method design pattern, but they look like this pattern. And then I will show you the real one. So why do you need a factory? The need for a factory comes when you need to encapsulate the complex steps to create an object. One famous example, let's say, in Symphony or in Drupal is the service container, the dependency injection container. The dependency injection container in Drupal is just a big factory for creating objects. But it doesn't follow this design pattern because the container can create different type of objects or services. When you follow this real pattern, that means you have one factory that creates one type of object and only one. And so the fact that you centralize this process or this algorithm in one single place, then it allows you to change it later on if you need to do some changes to your code. So you have to touch one single class instead of the multiple locations in your code where you are manually instantiating your objects. So this is not the real pattern, but this is a first approach, which is called the static method approach. As you can see this class, MediaFactory has a static method to create a media based on the extension of the file. So if it's a PDF extension, then we create a PDF file object. If it's a text extension, then we create a text file instance. At least that's not too bad to do that because at least you have centralized, sorry, you have centralized the creation of your objects in one location. So if you want to change something, you just change it here. And in your code everywhere you use this class or this static method, then you will reuse this code. But this implementation has many, many lacks. As you can see, I want to use this MediaFactory class and this static method in another object, which is called document repository. And the problem here is that I'm using the class here, MediaFactory, I'm strongly typing MediaFactory, which leads to a tight coupling between this object and this object. Remember, the solid principle, you should not depend on concrete classes. And this is a concrete class. Also, this code is not following the OCP principle, the open-close principle. If I want to swap this factory with another one, I will have to change the document repository class. So my code in this case is open to modification instead of being close to modification. So this is why the static factory approach has lots of lacks. A better way to do this is to remove the static keyword. So as I said, we have advantages of this approach. It's simple, it's pragmatic, but it introduces tight coupling between objects. So if you really want to make this better, you just remove the static keyword and you make it a real factory instance object. As you can see, my class also implements an interface. So this way, I will be able to type in in my document repository class. I will type in with this interface. And so this way, I will be able to change this factory with another one, which implements the same interface. So my document repository class now looks like this. As you can see, we have a dependency with media factor interface. So here I'm using dependency inversion principle and I'm also doing dependency injection because I'm injecting the dependency. This way, my document repository object just know about an abstract type, just know about the interface. And the interface says that we have this createMedia method, which takes a path and returns some objects. But the problem is, this method can return different type of objects. Image file, PDF file, text file, and so on. So I don't exactly know what is the real type of this file object. That's better. So if you at least want to make simple factories, you should do that in your own code. Okay, so it's simple, it's a very pragmatic approach. We have a loose coupling between document repository and the factory. We are leveraging the dependency inversion principle. We can easily switch the dependency with another one. So this code is following the solid principles. But it's still not a real factory method design pattern implementation because this object, this factory, returns different types of objects. So this is the real one, this is the real design pattern, which is called factory method. You have an abstract type, creator, which is the interface of the abstract class. And this method, operation, the public method, is usually pre-implemented in this abstract creator class. But this method, at some point, delegates to this protected factory method. This is the real factory method. This is the method that will instantiate the real object, the real class. But this method here is protected and abstract, and it must return some object that inherits the base abstract product type. And so remember that the pattern, the factory method design pattern, states that you have an interface and for defining the interface. But the responsibility of creating objects must be delegated to the concrete implementations. So the protected abstract method must be implemented by the concrete factory class, the concrete creator, which produces a concrete product, which extends the base product class. So the example I chose, you will see, is a media management system. I would like to be able to analyze media files like pictures, movie clips, and let's say sounds. And I want to be able to extract the metadata of those files, let's say, to import them somewhere in the database for storage, for instance. And I want to make it in a way that my system is flexible if I want, at some point, to analyze PDF files or Word files or whatever kind of files, without making too much changes in my code. So I can use this pattern to do that. This is how it looks like in the end. So this is the UML diagram. We have the abstraction, the abstract media metadata factory, which produces metadata objects. And so every file on your file systems share common stuff, like a name, a path, a size, a creation date. But depending on the file type or the file type you will analyze, you will want to get more specific metadata. For instance, for a picture, you want to retrieve the size of the picture, the width and the height. For a movie, you want to get the duration. You want to get the number of frames in the movie. For the sound, you want to get the bit rates and the duration as well. So this is why those classes will also allow you to know the extra specific attributes of the files. And so as you can see, my image metadata factory object, this factory will only produce this type of object. And this one will produce this one and this one will produce this one. So one factory creates one type of objects every time. If tomorrow I want to analyze PDF files, I will create a new class, a new factory class, and a new PDF metadata object. So two classes to create. But I will not touch the existing classes to not break the code. So this is what I want to achieve. I want to have an image metadata factory object which delegates to some analyzer object to analyze a picture. And when I load the metadata for a file, it returns an image metadata object which extends metadata. So these methods are the one taken from the base class, the base product class, because they are shared for every file. And those methods are specific to the image metadata class. And that's the same if I want to analyze movie clips. I have a movie metadata factory which has a video analyzer object and which produces a movie metadata object. And from this object, I can get the duration, the resolution, the frame rate, and so on. So this is basically how to achieve it. You have these base product class. This is the base metadata class, which defines all the shared attributes for every file. Then we have the abstract factory class, which defines the methods, which is this one, load metadata. This is the public method. And as you can see, at some point, we call this protected abstract method, which is implemented by every factory implementations. And this creates metadata method here is abstract. And it's delegated to every implementations. So my image metadata factory class will simply implement this method. So this is the class that defines what's an image. So an image extends the media metadata class. And I also want to store the width and the height for an image plus the getter method to read those information. And so this is basically the factory class. This one, image metadata factory. I implement create metadata. I will analyze the file with my injected analyzer. And I will simply instantiate image metadata. So the initialization of this object is centralized in the factory. And everywhere I need to analyze images, I will inject the factory to ask the factory to load the metadata for an image. So this way, I can easily change the algorithm to produce an image metadata object at some point. This is the analyzer class, which just uses the get image size function of PHP to read the data. And in return, they simply PHP array. And then I'm using it to read the width and the height. And so then you can repeat this for every other factory, for the movie factory, for the sound factory, for the PDF factory, and so on. So as you can see, with this powerful system, I can make my system much more flexible. If tomorrow I need to support PDF files, I will just have to create two or three classes. The PDF factory, the PDF metadata, and the PDF analyzer object. But I will not change the existing classes in my system. As a downside, you create many classes. So you make your code a bit more complex. So this design balance fits very well for complex applications or for frameworks for instance, because frameworks need to be very flexible. And this is why in Symphony we also use this design pattern to make the framework flexible. All right, makes sense? Good. So now the structural patterns, I will show you these. Two patterns, the composite and the decorator. The family of structural patterns allows you to make your code flexible in a way that implementations will be separated from their interfaces. This way you can easily replace an object by another one, for instance. Or you can easily extend an object without changing the code. So the first one is called composite. This one is very simple to implement. A composite object allows you to treat single objects or collections with the same unified API. So it's very useful whenever you have recursive representations or nested representations like file system, file explorer, where you have directories and files and the directory can also contain subdirectories and subdirectories and so on. If you have to parse an XML file, for instance, because an XML file has nodes, which contains nodes, which contains nodes and so on. In Symphony we use this pattern a lot in the form system because the form class can have nested forms, you can create complex forms. And so when you submit a form, then the main rule form will call the submit method on every of its children. And each child will also call the submit method on its nearest children. So the operation is recursively applied to the whole form tree. So this is what it looks like. You have an abstract type called component. It can be just an interface or an abstract class. You have a concrete object, a leaf, and you can create a composite and the composite can contain any component, so any leaf or any other composite. So you can have this, for instance, I want to use my concrete object and perform this operation on my concrete object. I can create a composite, which combines two leaves objects. And so the operation method will iterate over the leaves and call the operation method on each leaves. They can also inject the simple composite into my super composite because I can have composites of composites. So this is how this pattern works. So it works well for collections. And so in my system, in my example, I would like to make an e-commerce website where I want to be able to sell products, physical products, digital products, or combos. So I want to be able to sell a combo of products for a cheaper price, for instance. So this is how it looks like. You have the base product class. Each product has a price and it has a mass. As you can see, the mass and the price are represented as objects because it's easier to manipulate objects than manipulating scalar values or floating point numbers, especially for prices. And so each other class extends this one and you can see the combo is, it combines, it encapsulates any numbers of products, which can be our product, physical products, or other combos. So this is the base product class, which receives a money object to define the unit price and a mass object to define the mass in grams because I want to be able to know what's the total mass of a combo, for instance. This is my digital product class. A digital product, this is not something that you want to chip. So it doesn't have a mass, just something that you can download on your machine. So the mass is zero gram. So I can create my art product, which has a price of 49 euros and 960 grams, for instance, for the paper book. I'm using object here because this way I can easily, let's say, use or define the masses has grams or kilograms or whatever and the object will normalize everything to grams so that it would be easier to add masses together. And so a digital book doesn't have any mass, it just has a unit price. This is the combo class, this is the composite. Combo is the composite object. So it receives an array of product, this is the product that we want to put in the combo and I can choose whether or not to pass a unit price. If I pass the unit price, that means this will be the price for the combo, whatever the prices are for the inner products. If I don't pass any price, then by default I will calculate the total price of every product in this combo. All right, so this is what this method does, get total price. Same for the mass, I want to know what's the total mass of the combo. If I want to buy, let's say, a TV set and a PlayStation then I want to know what's the mass of this combo if I want to make it cheap to the customer and how it will cost for the web shop to pay for shipping it. So as you can see, my total price method here calculates the prices and as the price is an object, it's a money object, we have an add method. So I can add money objects together, I can add money A with money B which returns money C, which is the sum of money A and money B. And I can repeat the same for the mass. I can add a mass with another mass to get a third mass, which is the sum of two masses. So I don't really use scalar values, scalar types in my system, I always use object even for very simple concepts like monies and masses. So for instance, I want to create a simple combo here. This combo allows you to get a digital camera with the bag and the SD card for this price, so 803.39 euros, so the price is in cents because it's easier to deal with cents instead of euros, especially if you want to, let's say, let the customer pay three times without any interest, for instance, and you don't want to use any sense, you don't want to lose any sense in the payment. So this is why in the money design pattern, we always express the amount of money in cents. So that means this combo is sold at this price, so we don't care about the sum of every single unit pricing. But if I don't pass any price, then the total price will be the sum of every prices in the combo. And I can also make super combos, so combos of combos as it's a composite. So as you can see, we have the first combo, which is this one, and I also want to add an extra product to make another super combo on top of it, which I will sell with this price, or with a custom price. So as you can see, this design pattern allows to make your code very flexible when you need to make the same operation recursively on an object and it's children, right? Make sense? Now, the next one is probably one of my favorite design pattern, the decorator design pattern. As you will see, the decorator design pattern is very similar to composite. It looks like composite because it uses composition of objects, but it solves a very different intent or a different problem. The decorator design pattern allows you to extend an object capabilities without changing its class. So you don't want to change the class of the object that you want to extend, but you want to create new classes to envelope or to wrap the object that you want to extend. This way you can make any complex combination of decoration. And so remember when we talked about solid design pattern, the solid principle, we should not have classes with thousands line of codes, so this is why I don't want to, this is why I will use decorator design pattern because this pattern will force me to create new classes for every new responsibility that I want to attach to an object. And it also allows you to follow the open-close principle. Again, you don't want to touch the existing class if you want to extend the class. You want to create new classes and envelope the object to dynamically add new capabilities or new responsibilities. So you can hear about decorator, that's the original name. Sometimes you can also read wrapper as the other name for this design pattern. So this is how it looks like. As you can see, it's pretty similar than composite. The thing is we have this abstract decorator class which wraps a decorated component. And the decorated component can be a concrete component or it can be a decorator because we will type in with the base abstract type, which can be an interface or an abstract class, for instance. And then the operation method from the base interface will then do some stuff and then delegate to the operation method of the decorated components or the wrapped components. So this is how it looks like as a usage. You have your real components and you want to extend it. You want to add new dynamic responsibilities to this object. So instead of modifying this class, you will basically create a new class that will decorate this object and that will reimplement the operation methods. You mainly encounter this design pattern for logging, for instance. You have an object and you want, let's say you have a database object which performs database SQL queries and you want to be able to log the SQL queries made to your database. But you only want to log when you are in development environment. You don't want to log when you are in production environment. So instead of injecting a logger object in your database object, you will create a profiled database class which is a decorator for the original database class. So this way you have your database service for production environment and you have a profiled database service for your dev environment which wraps the original database object and which also receives the logger object to log any SQL queries. The example I chose is this one. Again, in my e-commerce system, I want to be able to let people use coupon codes to discount their orders. And so we have two type of coupons. We have rate coupons, so I want to get 15% off on my order. I want to have a value coupon, so minus 50 euros on my order. But to make those coupons eligible, we have to respect some conditions. For instance, the coupon is only valid for a period of time or the coupon is only valid for some very specific set of users or the coupon is valid on some very specific products in my shopping cart, not every product, right? So you can imagine all the ideas of restrictions that you can apply to a coupon. But the difficulty is that I want to make them cumulative. I want to create a coupon that I will give away to the people and I want this coupon to be valid for a specific period of time, but also we need to have a minimum amount of purchase amount in the shopping cart. And I want to give this coupon only to my premium customers, right? So how can I achieve these complex combinations of coupon restrictions? Then I can use the decorator design pattern in this case. As you can see, we have the base coupon, the coupon interface or the coupon abstract class. Each coupon has a unique code and we have a method to discount an order object. And so if I'm acting on a value coupon or on a rate coupon, those two classes will simply apply the discount on the order object. But if I want to add restrictions, then restrictions will be handled as decorators. So this is why we have a coupon decorator which is a restriction decorator. And this abstract class wraps a coupon object and it overwrites or re-implements the get code method. So the get code method simply delegates to the wrapped object. But the apply discount method has to be re-implemented by every single restriction class. And so what we will do is that if the condition, if the restriction is not valid, then the apply discount method will simply throw an exception or it will simply just do nothing on the order object. Otherwise, if the restriction is valid, then we will ask the next decorator to be applied which can be the value coupon, the rate coupon or another decorator. So we'll simply forward the method code to the next object, right? So for every restriction, you need a new class. Again, you will not change the order class, we will not change the coupon class. You just want to create a new class whenever you need to implement a new restriction for your coupons. So this is the value coupon. As you can see, the value amount for the discount is a money object. Again, I'm using money object because it's easier to subtract this amount of money on another amount of money. And so when I apply the discount, I will simply tell the order object to discount is it's total amount for this discount value. The rate coupon does mostly the same thing except that we have to calculate what's the amount to debit based on the rate that we have initialized in the construct method. And now we have the decorator, the decorator object, which is an abstract class. As you can see, the decorator wraps a coupon interface so it can be a rate coupon, a value coupon or any decorator object. The gate code method simply forwards the method code to the inner objects. And then I will have to implement the apply discount method in every concrete classes. So this is the first example, the limited lifetime coupon class. So this class in the construct method must wrap a coupon. It must wrap a coupon. And we also tell what's the begin date and the ending date for the validity period of this coupon. So I'm just checking that the validity period is fine. And then my apply discount method will check that the current date is between the validity period. If the coupon is expired or if the coupon is not yet usable, then I will throw exceptions or I can simply just do nothing on the order object. Otherwise, my job is done. So I will simply move or I will simply forward the method code to the inner coupon object. And this one would be able to apply the discount if it's a rate coupon or a value coupon. If it's another decorator, then the decorator will check for the restriction and then move forward to the inner objects. Okay, so I have my limited lifetime coupon which decorates a value coupon. And so I want to discount 20 euros on another object. And this one will discount 25% on the order object if we are using the coupon on this lifetime period. Okay, this is another one. The minimum purchase amount coupon decorator. So you need to have a minimum amount of ordered objects in your shopping cart to make this coupon eligible for discount. So again, I'm wrapping a coupon object and I'm telling what's the minimum amount of money we need in the shopping cart to make this coupon eligible. And as money is an object, my money class has a less than method so that I can compare two money objects together. So I will check that the amount is greater or lower than this minimum amount. But I will also check the currencies because if I have USDs compared to euros, that's a clash. So we'll have some currency mismatch exception at some point, all right. Otherwise, if we have enough amount of money, then we can forward the method call to the inner objects. Okay, so again, this is how you can use this. You can use this class minimum purchase amount coupon which wraps a value coupon or a rate coupon. But now with the decorator, with this system, I can also make things much more complex. I can have a value coupon which is decorated by a limited lifetime coupon which is decorated by minimum purchase amount coupon which is decorated by customer first order coupon. So you can imagine any complex combination of restrictions for your coupons. And then if you want to go further, this is the way you can use it. But if you have, let's say, an admin system to let the administrators create coupons with restrictions, then you can store this metadata in some storage engine like a database. And then with a coupon factory patterns, you could then reassemble the whole coupon restriction sets within a factory. Okay, so you can combine decorator with factories to make super great design pattern implementations. All right, so the decorators, as you can see, it allows us to leverage the single responsibility principle because we have small classes which are focused only on what they have to do. We don't change the existing objects. So we follow the OCP principle, open-close principle. We can make any complex combination of restriction sets. We can also decide in which order we want to apply the restrictions, okay? Sometimes it doesn't make sense for our use cases. We can, for instance, switch the order. Doesn't really make sense. Sometimes it may be important to have one decorator to be executed before another one, especially when you do caching, for instance. We can use the decorator design pattern for caching. You have a REST API object, and you want to cache the result of a REST API. So you have a cache, cached REST API decorator. And on top of this cache REST API, you want to have some authorization layer so you can have an authorized REST API. And so by decorating the layers, you will be able to make your REST API more flexible. Some downsides with this pattern is that as you start decorating, the variable you will use, so in this case, the coupon variable is now a customer first order coupon. So it's not a rate coupon, no a value coupon. So I don't know the real decorated object anymore. So I can't use instance of keywords in my code to check if it's an instance of rate coupon or value coupon because it's decorated. So that can be a limitation for your code. Also, if you have classes with lots of public methods, and if you want to decorate this object, then you have to, for every class, for every decorator class, you will have to reimplement all this method and make the forwards method calls. So you may end up with some code duplication at some point. Also, the decorator design pattern doesn't work if your object returns itself. So if you return this in a method, then you break, you will break the fluent interface that you designed by default. Yeah, so that's the main limitations of this design pattern. All right, 15 minutes left. Make sense? Good. All right, so the last one, last design pattern, which is a behavioral design pattern. So as I said, the behavioral patterns family is a set of design pattern which help objects communicate with each other, and they will also leverage decoupling. So the goal is to achieve decoupling between your objects. So you have all these patterns below. For instance, the strategy design pattern is very famous. You probably already know about it, or you probably use it already without knowing. Remember, in my first slides about the factory design pattern, when I've injected the media factory interface in my document repository, that's basically a strategy. So I also used a strategy design pattern. If you use Symphony or Drupal, maybe in Drupal 8, you probably use the event dispatcher component to dispatch events or to connect listeners to events. The Symphony event dispatcher is an implementation of this mediato design pattern. This is a mediator. The pattern I will show you is the visitor design pattern. So the last one, it's one of the, the one that is the least known pattern, but it's very easy to use, as you will see. So basically the visitor design pattern allows you to decompose an object which has data and operation. So basically you will move all the operations into separate classes, and you will just keep the data in the class. So this way we have the data objects and operations has other objects. So this is what it looks like. You have the objects that you want to visit. So this is the visitable objects which can accept a visitor as an argument. And the visitor concrete object will visit the element. So basically when the element, when you call the accept method on the element you want to visit, then this method will simply just make one single statement which is calling the visit method on the visitor and inject itself into the visitor. Okay, so as you can see the accept method takes a visitor. It simply calls the visit method of the visitor and injects itself so that the visitor knows about the visited objects. Well, this is what it looks like.  So you can then accept any visitor implementation in your visit method, visitor A, visitor B, visitor C, and each visitor does things with your visited objects. So this is my last example. Consider a shopping cart in your e-commerce system. And so in your shopping cart you can push products. So for each product you have some names, some quantity, some unit price. And so in this shopping cart object, so this is how I want to use my shopping cart. So I want to add products. So I want to order three bottles of shampoo. I want to order one kilogram, 38 of salmon, and this is the unit price per kilogram for the salmon, for instance. So this is my shopping cart. And when I check out my shopping cart, I would like to know the total price of the shopping cart or I would like to print a receipt or I want to generate a receipt as a PDF, for instance, or I want to reorder the list per category, or as you can see we have the categories for each product. So in the receipt I want to have all the product ordered by categories. So naively I could do those operations in the shopping cart class. I could have a method to get the total price. I can have a method to resort to the shopping cart by categories, or I can get a method to issue the receipt. But as you can see, this method, for instance, issue receipts doesn't really belong to the shopping cart. Basically, you don't want to have a strong coupling between a shopping cart data object and some PDF generator objects. This is a side operation that you don't want to directly do in your shopping cart. And if at some point you want to add new operations, let's say you want to discount the shopping cart because we have a loyal customer, then that means you have to add a new method to this class. Remember the open-close principle, you should not change the class if you want to extend it. So this tells me that I should move these operations somewhere else in my system. And the visitor design pattern can help us to achieve this. So basically my shopping cart object will simply store the list of ordered products that basically what we have, and some public get a method to read these list of items. And I will implement my accept method, which can accept any shopping cart visitor object. And so the visitor will visit the shopping cart, so shopping cart inject itself into the visitor. And so for each operation will be a single visitor class. So for instance, we have the total price cart visitor, which is the total price calculator. So when we visit a shopping cart, then we iterate over the items of the shopping cart and for each item we calculate the total, subtotal price. So the quantity times the unit price. And then we add it to the main total, okay? And so the main total has been updated. So we have a new money object. So I erase the previous one and update the new one. And we have then a get total price method that returns the computed total price. As you can see my visit method returns void. There is no return value because as we can have different types of visitors, we can't define in the interface what could be the return value of the visit methods. So this is why your visitor must store the computed values, has properties and then offer get a method to read those values. So the visit method just does things but it doesn't return anything, all right? So I have my shopping cart, which is populated with items. And then I want to get the total price of my shopping cart when I check out this shopping cart. So I will accept a visitor. The visitor will calculate the total price and then I can ask the visitor, what's the total price of this shopping cart? And that's done. If I want to test this class, it's super, super easy because we just have 25, 30 lines of code in this calculator visitor. Same if you want to reorder the list of items per category to display them on the receipt, for instance. Then again, I will create another visitor which will do this operation and it will update this attribute and I will have a get a method to read these attributes. And again, I can accept this visitor which does what it has to do and then I can get my list of ordered items per category, done. I can unitize this class separately without changing or without touching the other classes. So as a conclusion for this visitor and for the end of the conference. So the visitor design, as you can see, it's very simple. You just have two interfaces, the visitor and the visited object. So it allows you to separate the data, the data objects for the shopping cart, for instance, which contains data and the list of operations you can apply on these data objects. Operations are implemented as visitors. It encourage you to follow the single responsibility principle because you create new classes for every new single responsibility or any new tasks. Again, we don't change the existing shopping cart class. So we follow the OCP principle. We just create new classes for extending the shopping cart, for dynamically extending the shopping cart. So we now have loose carpling because my shopping cart doesn't know anything about the PDF generator. If I want to generate a receipt as a PDF, I just create a new visitor but only the visitor knows about the PDF generator, not the shopping cart object. So we have loosely capital code which means less HKCs or less problems when you make a change in your code base, less frictions. Some downsides of the visitor design pattern is that your visitor object must be mutable which means they can only be used once per visited object. So you can't reuse a visitor after it has been used by a visited object. Also you should not mutate the visited object inside a visitor because if you have another visitor running after the first one then it may have a state that is not coherent for the algorithm. So the visitor should only read the state of your visited object but not mutated. Which also means that your visited object must expose its public state, its public API. So you must expose with getter methods. And finally, we can't use what we call double dispatch if you read articles about this visitor design pattern. You will learn about double dispatch. Double dispatch is not supported in PHP because we would need to have polymorphism. Polymorphism is when you can define the same methods multiple times with the same name in the same class but with different arguments. So in this case we can only have one visit method but not multiple ones. So we can't use double dispatch in PHP. I think I'm done. So thank you for your attentions. I hope you enjoyed the conference. The slide date is already online on my speakerdeck.com slash H-H-A-M-O-N. You will also get the slide date from Drupal website. We have three minutes for questions. So yeah, there is a microphone. Yeah, hi, thanks. It's a great talk. So the decorator pattern, I noticed you're throwing exceptions. Uh-huh. I thought that was throwing exceptions but actually writing behavior against it. So I thought like you're not gonna do that. Is that kind of inherent part of decorator that you have to throw the exception and then... It's up to you if you want to throw an exception and then catch it to do something or if you just do nothing, you just forward the method code. If there's nothing, there's nothing to do. It's up to you. Okay, so it's acceptable too. Yeah, cool. Thanks.


Hello, hi everyone, I am Sanjay Gupta. I welcome you on Sanjay Gupta Tech School. So today we are having day 21 of this C and C++ coding boot camp and yesterday I explained the concept of structure briefly and in today's session, I will be explaining few more concepts related to structure. So we'll be implementing couple of programs as well, right? So in yesterday's session, I told you like how you can implement a structure and it's variable and how you can do some implementation. So today I will be creating arrays of structure, right? So in today's session, you will actually understand the application of structure, right? So before starting the session, I just want to give my introduction. So if you go through this slide, you will get to know. So if you are following me from other boot camp, so I think you know about me very well. But if you are for the first time on this channel, so you can just go through with this slide. I am running Sanjay Gupta Tech School as founder and instructor doing career coaching as well for lots of folks and worked in Salesforce, Traction, Aperio, having 16 plus years of experience and helping students, freshers and professional so that they can ramp their career in Salesforce ecosystem or in IT industry. So I have created a telegram group. Okay, before that, I just want to say consistency is the key. So if you're following this boot camp or any other boot camp, so do regular practice because if you do regular practice, then only you will be able to understand the concepts very well, right? Okay, now I have created a telegram group where lots of folks are connected. And if you face any difficulty while learning C or C++, so you can scan this QR code and in that telegram group, you can ask any question. I will be there to answer your questions. And you can follow Sanjay Gupta Tech School on YouTube, LinkedIn, Instagram, Telegram and all the important links are available in video description as well. So if you want to find all the session links together, so there is a session tracker which is available in the video description. Okay, so now I'm going to start with the topic. So we are discussing structure in C programming. So yesterday also I discussed about this topic. I hope you followed that session. So today I'm going to implement one more program related to that, right? So yesterday I implemented this program like we have a student structure where name, roll number and marks variable is created. And I just demoed you how we can receive information of a student and how we can display that. Now in today's session, you will get to know how we can create more than one variable of structure, right? So just go through with this requirement where it is mentioned like write a program to read height of two persons in feet and inches and print their sum, right? If after addition inches are greater than equals to 12, then we need to convert them into feet as well, right? So this is the requirement that we need to implement, okay? So for height, we have two things. One is feet and one is inch. So I'm going to create a structure, okay? So I am just erasing this code, like I'm just going to modify it. So name of structure will be height and here I will be having in feet and inch. So these two members will be there in the structure, right? Now here I will be creating struct height, then h1, h2 and h3, okay? So this way I have created the variables. So here you can see h1 will also be having memory for feet and inch, h2 will also be having memory for feet and inch and h3 will also be having memory for feet and inch, right? So after creation of structure, you just need to create its variable and structure variable can access any member of the structure, right? So now I need to read first members or first person height. So enter height of first person. So here I'm going to write h1.feet and h1.inch. Then I'm just copying and pasting it. So enter height of second person. So here I am writing h2.feet and h2.inch, right? So what will happen? h1 is a variable of structure. So this variable can access feet and inch. So first person feet and inch, whatever height is. So those feet and inch will be stored in this parameter. And for second person, this h2 will be storing feet and inch, okay? So this way we will be having the input from the user. Now we need to perform the addition operation. So I'm going to write h3.feet equals to h1.feet plus h2.feet. So h1.feet means first person height feet and h2.feet means second person height, the feet value will be added and it will be stored into h3. Then we need to write h3.inch equals to h1.inch plus h2.inch, right? So this way addition will take place, okay? Now if you want to display the results. So what I can do? I can write feet equals to person d and then h3.feet. So after addition, the feet, addition will be available into h3.feet. So that's why I'm using h3.feet here. Now I just need inches. So I'm writing index again and here I'm writing inch equals to person d h3.inch, right? So we just did some addition operations and then the result will be displayed with the help of h3.feet and h3.inch. Now I'm going to run this code, okay? So I'm executing it. So here I need to enter the height of first person. So I'm entering five feet and seven inches. Then I need to enter height of second person, right? So second person height I'm going to enter. So five feet, eight inches, right? Now you can see the result. So feet was five and five. So total feet is 10. Inch was seven and eight. So total is 15. So we all know mathematically if inches are equals to 12. So it is equals to one feet. So from these 15 inch, we can subtract 12 and we can add one into feet. So that 12 inches can be converted into feet. So actual result will be 11 feet and three inches. Okay, now we need to do that. So here after addition operation you can apply if condition. And inside this if condition what we can write we can check value of inch. If it is greater than equals to 12. So what we can do, we can increase feet by one and we can decrease inch by 12. So this will be the logic for conversion. So we are increasing feet by one and we are decreasing inch by 12 because 12 inches equals to one feet. So after this calculation result will be appropriate. So again I will be entering the same data. So I'm clicking on a run again. I'm entering five feet, seven inch and five feet, eight inch. So you can see the result. Feet is 11 and inches three, right? So earlier it was 10, 15 but right now it is 11, three. So this way I hope you are able to understand the uses of structure. So unnecessary, you don't need to create lots of variable. So common variable you can create under structure and then that structure variable you can create and you can use it, okay? Now after implementation of this program I just want to have another topic that is structure versus union. So similar to structure we have another data type. Similar to structure we have another data type that is known as union, right? So here you can see both are declared similarly. Similar to structure you can create union and here we have different type of variables like ABC. A is of int, B is of float, C is of care. Similarly we have union where we have the variable and different data types. Then at the bottom you can see we have memory allocation. So this is the difference. If you are using structure, so in structure if you create any variable. So here we have created a variable n. So just after structure declaration you can create a variable. So for this n, this memory will be allocated and each member of structure will be having separate memory block, right? Each member of structure will be having separate memory block. But if we talk about union, so in case of union any one member will be occupying the memory and how we will identify the member. So the member which will require highest amount of memory. So equivalent to that member, memory will be allocated and other members will be sharing that memory, right? So this way if you want to save your memory then you can use union. So in union the limitation is at a time you can store value into one member. So here we have three members. We have A, B and C. So either you can store value into A or B or C. If you store value into another variable so previous value will be erased because we are sharing same memory, right? So sometimes to save memory and if you already know like we just need to store value into any one of the member and if we replace it with another value so previous value we don't need at that point of time. So in that case you will use union. So now if I move forward here are some key differences between structure and union. So if we compare structure and union so both are basically user defined data type. Both structure and union are user defined data type, right? Why they are user defined because the declaration we need to define like what all members will be there in structure and union. Then structure basically allocates separate memory blocks for each member. So if you are having three members three blocks will be there. If you have five members so five blocks will be there. In case of union memory will be allocated to the member who requires highest amount of memory and other members will be sharing that memory location, right? So this is the basic difference between structure and union if we compare the memory thing, right? And we can store values to each member of structure at same time because we have different memory locations but in union we cannot do so because in union at a time we can store value into one member, right? So whenever you want to save memory and you want to reuse the memory for different different members so you can use union and if you have enough memory you want separate memory for each member then you can create structure. So declaration for both the data type is same but the uses are different. So if you are a BTEC student so for you this is an important question that comes in the exam and if you sit in the campus placement and interviewer is asking about CNC plus plus so this whole bootcamp will be beneficial for you to revise all the concepts in one go, right? And if you are non-technical folk and you are just learning your first programming language so for you all the concepts which we are discussing in different sessions so all those are very much important for you. Now we need to learn what is array of structure. So array we already discussed in previous session like if you want to store a similar type of elements then we create array. So now we have created a structure, right? And if you want to create array of structure so that is also possible but before that we need to understand the requirement like in which situation we will be creating array of structure. So in yesterday's session I demoed you how to create student structure so that we can store information of one student now in today's session I will be showing you through the same structure how you can store information of 10 students, right? So for that we will be creating array of structure. So here you can see we have name, roll number, marks so we need to process it for 10 student and then we need to filter out name and roll number of those students whose marks are greater than equals to 75, right? So I won't be creating much variables and you will get to know how it is being implemented. So first of all I'm going to create roll number then I'm creating name, character array and then for marks I'm using float. So this student structure we created yesterday as well and the same I'm creating today, right? Now the difference is yesterday I created one variable from the structure like struct student s so this way I created one variable yesterday. Now what I'm going to do I'm going to convert it into array. So this is now basically array of structure. So this s is one variable which can store 10 student information and those 10 students information are different like roll number, name and marks having different data type. So first you will be creating the structure and then you can create its array and the same concept is available in object-oriented programming as well. So in object-oriented programming like we create class and after creating class we can create its list that is similar to array, right? So if you are learning Java or Apex then you can understand otherwise I will be explaining these things in C++ also. Okay, so here we have created an array. Now to iterate this array we need one variable that is I so I'm just writing here enter roll number, name and marks of 10 students. Now we need to implement a loop. So I equals to zero, I less than 10, I++ and inside this for loop we are going to receive the data. So now here we need to write s of I dot roll number. So s is array, array and then I will denote the index number because we have 10 elements that we need to store and at each index we will be having three members, roll number, name and marks. So after dot you need to write roll number then we can receive name, right? So this way with the help of this loop 10 students roll number, name and marks will be received and at different indexes they will be stored. So initially for roll number, name and marks index will be zero. So at zero index all three information will be stored then I will be incremented to one. So on one index three information will be stored. So this way there will be 30 blocks. So for each index there will be three blocks and the results, sorry, the input values will be stored accordingly. Okay, now we need to filter out the values. So this is the print f information of students having marks greater than equals to 75. So here I'm writing for I equals to zero, I less than 10, I plus plus. Now here I need to write if condition. So if s of I dot marks greater than equals to 75. So s of I means that particular index. So initially index will be zero. So s of zero dot marks, zero index marks if it is greater than equals to 75. So what we need to do, we need to display roll number and name. So this way I think you will be able to understand. So initially roll number and then name will be displayed. Only those roll numbers and names will be displayed where marks is greater than equals to 75. So this way you can see how we implemented this code. So first of all we implemented a structure. Then that structure is converted into array of structure. So this is basically array of structure. Then with the help of this loop, we are receiving input and then we are processing that input data. Right, so initially I'm going to execute it for four times. Initially I'm going to execute it for four times. So array size is four and both the loops are going to execute four times. Okay, so now I'm going to run this code. So here you can see it is asking for roll number, name, okay. One thing I didn't modify it, so it should be four. Okay, so just correct it like it should be four. So here we need to enter four students information, not 10. So roll number one, name I'm entering Ajay and marks I'm entering 200. Then second student roll number two, Sanjay marks 100. Okay, now here you can see it is giving incorrect information. Right, so there is one catch that we need to see. So one thing I use percent D, so I need to use percent F here because marks is of Thai float, right? And after get us, I just need to use get care because whenever you are entering something and I think get us will be working fine. Let me just check it. I'm going to run it again. So entering one Ajay 200, two Sanjay 300, okay, something wrong here. M percent S of I dot roll number, okay. I just declared it as int, I just need to remove it. Let me just run it one more time. This time also it is not receiving all the data. Okay, I'm executing it one more time. So yeah, this time it is working fine. No, but it took first two students data and it is showing that as well. So actually there is some thing that is not working fine with this get us. So maybe instead of this, I'm going to use scan F percent S, M percent or maybe directly S of I dot name. Name, okay, I'm going to run it again. So I'm entering name Ajay roll number one, marks 100. Then Sanjay 200, then Vijay 300, then Ram 400, yep, now output is correct. So instead of get us, you can use this scan F percent S. It would work fine. So all the students are having marks greater than 75. So their information is showing if I run it again. So this time I'm going to input different values. So let's say 100, Vijay is getting 50 and Ram is getting 70. So you will see two students roll number one and two, right? Who are getting marks greater than equals to 75, right? So this way I hope you understood the concept. Now we have one more example. Like we need to read name, number of pages, price of 10 books. And now we need to filter a name and number of pages of those books whose price is between 500 to 1,000. So here I'm having page numbers, the name, it should be book and then price. Then it should be book. Then I'm using B of four. Then here I'm writing enter, name, pages, price of four books. So first of all, we are reading name. Then we are reading pages, page number and then price, right? And here information of books having price between 500 to 1,000, right? Now here I need to write B of I dot price. So if price is greater than equals to 500 and B of I dot price is less than equals to 1,000. So this way you will be framing the condition. So here we have two conditions. Price should be greater than equals to 500 and price should be less than equals to 1,000. Then we can show pages name. So here we can write B of I dot page number and B of I dot name, right? So this way the program is modified.  So we need to enter the name. So let's say first book name is C, number of pages 1,000 and price is 800. Then C plus plus 400, 7,000, then Java, 1,300. Then Salesforce, 2,000 and 1,500. So here you can see it is showing two books, C and CPP because these books prices between 500 to 1,000. So C is having 800 and the CPP is having 700. Java is having 300 and Salesforce is having 1,500 which are out of range, right? So this way I hope you are able to understand the uses of area of structure. Okay, so this is what I planned for today's session. I hope you understood whatever I explained. So do practice whatever scenarios I have implemented and next week I will be having more sessions on different topics. So you have session tracker with you. So if you go to the session tracker, so here all the topics are listed. So in the session tracker here we have a tab, code in C and C plus plus. So next topics will be pointers, then functions and then array, sorry, file handling. So next three weeks then we'll be jumping onto the C plus plus, okay? So this is a common sheet of Sanjay Gupta Tech School where all the tabs are available, different boot camps are available here. So you can follow them as per your requirement. Okay, so with this note I take your leave and we'll see you in the next session. Thank you for watching this session.


Hi, beautiful. So, have you ever been to a salon, sat down to get your hair done by the stylist? They're like, what do you wanna do with your hair today?  And then you're sitting there saying things like, I want bright highlights starting at my eye, going down and getting lighter at the bottom and like a little bit of darkness over here and over here. And your stylist is just like, what? What are you talking about? And then the stylist proceeds to use big words like baby lights, balayage, hair painting, root shadows, root smudges. And you're like, who is that? I don't know anybody named Root Smudge. Well, today I'm here to help mend hairstylists and clients and bring peace to the world. Maybe not a lot, but like just a little bit. So, we're gonna go over all the tricky words and phrases. So, by the end of today's video, you'll have a much better understanding of highlights, how they work, how they're done, and how to ask for the kinds of highlights you're looking for that way you and your colorists can be on the same exact page and you will get the hair of your dreams. So, let's do it. Woo! So, what are highlights, Brad? Let's start with the absolute most basic of basic, just making both get a clear understanding of what we're talking about today. The word highlights really just describes the lighter pieces put into the hair to add dimension to the color.  Everybody could use highlights in some which way. Hair color just looks better, more natural, and more professionally done when there is a highlight involved in the color process. Now that we know the absolute basics of what a highlight is, let's move on to some examples of different kinds of highlights and I have quite a few for ya. So, get your notepad out, start taking notes. We're gonna go over a lot of things today and hopefully it'll help you. So, let's talk about full saturation hair painting or balayage. Balayage, I don't know where exactly that word came from, but it's a interesting word that a lot of people can't pronounce. They say bulayage, they say balaj, they say belayage, like I've heard everything, everything, and I laugh every time. So, I like to refer to balayage as hair painting, it's just easier, it makes more sense in people's heads. Just go with that, hair painting, people will know what that is. So, here's an example of full saturation hair painting.  So, you're not only painting the surface, you're painting the underneath of that surface and making sure all of the lightener is fully saturated on the hair strand to make it super thick and creamy and have a lot of lightener on each strand of the hair. This will give you a super dimensional, chunky, beautiful highlight. And don't let the word chunky scare you. I try not to use that with clients because the word chunky just brings people back to like the 90s when we were doing like awful chunky highlights. I mean, it was cool back then. Don't get me wrong. But a lot of the time we start off with chunkier highlights and then we do something called a root shadow which we'll get to later. But full saturation painting is something that I do on most clients just because it is the most bang for your buck and you can get a lot of surface area covered in a short amount of time and it creates a beautiful result as seen in these photos. And that's full saturation hair painting or balayage is when you paint both sides of the hair and make a beautiful highlighted strand with your lightener. Okay, next let's move on to partial saturation hair painting. Now this is hard to decipher between full saturation hair painting and partial. They can pretty much be intermixed as much as you want. I am a full saturation kind of girl because I like to, you know, get it done fast and I like to get it a heavy highlight in there. However, there are clients say they have dark hair and they're looking for a tiny bit of lightness going through and they want it to look natural. You might just take the surface of the hair and paint the top of it instead of painting both the underneath and the top and fully bringing all that lightener through the hair strands. That way when their hair is blow dried and done it is a very subtle highlight effect that kind of just has a sprinkle of lightness going through the head and it doesn't look totally highlighted and fully saturated. However, you can also make a super dimensional blonde if you are only painting the surface because say when you lift your hair up or you flip your head over you're gonna see a lot of darkness underneath those highlights if you only do partial saturation you're gonna have all of that darkness staying on the bottom of the hair and then it's gonna give you beautiful dimension as seen in this picture which is also a beautiful look.  And then next time maybe we'll move on to full saturation and we'll add more and more highlights each time. That is partial saturation, hair painting or balayage and let's move on to the next thing. Let's talk about baby lights or a fine weave highlight. So typically these are done in foils because they use the extreme amount of heat to incubate them and make them super bright. Also foils are just a great way to organize your sections and keep everything neat and clean and tidy and beautiful and the hardness of the foil is just really easy to maneuver and to fold and to keep in place so foils are just a great option when your hairstyle is. So baby lights. This is a new term that people like to use when saying their weaves are super, super duper fine that you can hardly even see them and that's basically what baby lights are. So people usually use a tail comb, they slice a section out and they do a super fine weave of the hair and then the late on the foil, paint it with lightener and you can do just a few of these to make a very low impact result but a beautiful little sparkle in the hair or you can do a ton of them and have a really high impact blonde result. This will give you hardly any line of demarcation where you highlighted the hair. So the finer the weave, usually the less visible to the eye of where you actually got highlights done. So people like to do this to make a super blended look most of the time and it's a beautiful result if you have the patience for it, you can also combine baby lights on the top of the hair with full saturation balayage like we talked about before and it'll give you this kind of beautiful sparkly glow at the top with a really high impact full saturation highlighted at the bottom and that is something that I like to do a lot is combine both of those techniques and by the way, you guys we're going through all these techniques right now but most of these things you combine one, two, three different techniques on one head in order to make a creative masterpiece of hair. So baby lights will give you that very soft dimensional little sprinkle of highlights. Okay, next let's talk about sliced highlights. So instead of doing the weave like we talked about last time we can also do something called a slice which is my favorite. Listen, full saturation and slicing. Yes, give it to me right now. So a slice is literally just a slice. This is what it looks like. You just put the comb through, take that section and you put the foil on and you paint it with lightener. Slicing is a great way to get a lot of highlights done in a little amount of time. It is a great way to get high impact, high volume of highlights and do it very fast because you don't have to take that time to actually weave the highlight.  And then you can follow up with a root smudge or root shadow at the end in order to blend all of the seams. But it's a much faster, much easier approach to highlighting in my opinion. And also you can get a low impact result if you're taking very thin slices instead of thick ones. It'll give you a very soft dimensional look and if you skip more hair in between the highlights or less hair, it'll give you a different look there. But that is what slice highlights are. Okay, now let's go over what a toner or gloss is. Toner and gloss are lifesavers. I mean, they're pretty much the same thing. They can be changed out whenever you want to. I think gloss just sounds better. Toner is kind of like old school. But what people don't understand, I don't think is what really is a toner or gloss. Now toner and gloss can be used for so many different purposes. So it's pretty hard to describe it all. So I'm gonna do my best. As you can see in the pictures here, this girl starts off as a kind of yellowish-bronzy blonde. And then after she has more of a copper-brown highlight going on, so what they did to get to that end result is add more copper tones with a toner. And toner is a deposit-only color. It is demi-permanent. And the difference between permanent colors and demi-permanent colors is that there's no lifting that's going on to the hair. It is only depositing tone. So you can make the hair any kind of color you want with a toner. Now, typically when you're highlighting, toners are used most often to make the hair appear more ash-toned, get it more white, get it more vibrant. And so I find that a lot of clients will freak out about their hair when they see a little bit of their hair rinsed out.  Why does it look like this? Why is it so bright at the root? And you're like, we haven't added the toner yet. The toner will literally completely change your look in a matter of five, 10 minutes. So do me a favor or do yourselves a favor and do not come and complain to us about your hair until it is all finished and we start blow-drying it because a lot of the times the most magic happens right at that last 10 minutes of your color session. And the toner and the gloss can really change up the whole vibe of what we've been doing the entire day. So just chill until the toner is done and then you can complain or be happy, whatever happens, I don't know. Now that brings me on to our next technique which is a root smudge or a root shadow, as I like to call it. They're both interchangeable, they're both the same thing.  So I guess you could probably, I don't know, that just seems complicated to me. I like to just intermix them. People don't really know what you're talking about anyways so you kind of can just put that out there and say like, I'm gonna do a root smudge and they're like, okay, yeah, I do it. But let's just say root shadow today gives you that sort of bohemian grown out, lived in hair vibe that is quite current and is what most clients are looking for now. Nobody really wants that super bright, bright, stripy highlight right at the top of their roots. What I have right now is a root smudge. You see how it's pretty light at the ends but at the root, it looks like it's kind of growing out of my scalp? That's what's going on now. And also, hi new hair, how you doing? Oh my God. In a minute since I have not been platinum blonde, it's been like four years or something like that. I don't know, it's been a long time but I'm actually living for this. Let me know what you guys think about it. But root shadows are such an amazing lifesaver. You can really cover up any mistakes that you make with a root shadow. You can blur the lines between their natural hair color and the highlights you just put in their hair. So you can do super chunky highlights to start and then you can bring that highlight way back down to nearly their natural color with a root smudge or root shadow.  And it's just an easy way to make the hair look more lived in and more natural and not like you just stepped out of the salon. We could go into a lot more technical detail today but I'm not going to because I'll be here forever explaining root shadows and how I like to do them. Okay, next let's go over the money piece or a face framing highlight, whichever one you want to call it. Money piece just sounds like more fun to me but whatever you want to do. So we've gotten kind of crazy with money pieces lately.  I just think it looks kind of wacky and kind of like, wow, yeah. You definitely have some highlights going on there. It's a lot, it's a lot for me but that's what your thing is and do it. This is what a money piece looks like. It is that really bright highlight that goes like whoop or like whoop like all around the face. It's used to really draw attention to the face and literally put a frame around it. I think face framing highlights are great when they're done minimally. I just don't always love these super chunky front pieces. It's not my style and a lot of people love it and that's totally cool. But this face framing highlight can be done with all the different styles we just talked about say with foils, you can do it. You can do it with full saturation hair painting. You can do a partial saturation hair painting. You can then do a root shadow on it or a root smudge and you can do all sorts of things with it but that is what a money piece or face framing highlight is and that's that, that one's easy. Woo, those are all of the different kinds of highlights you can get. Now, I'm sure you can add a million different techniques onto that list but those are the super basics and basically all of the new highlight techniques are based off of those techniques. So if you know the basics, go from there. I hope after watching today's video you can better communicate with your hairstylist what kind of highlights you're looking to get from them because the better you explain what you're looking for the better we can give you that end result. Now, I recommend always coming in to the salon with photos and try to explain in as much detail as possible what you're looking for. That way, both of us can be on the same exact track and we can get you that perfect outcome because what happens sometimes is when a hairstylist is not that experienced is they may not know how to have a proper consultation and sometimes the consultation will end short and sometimes these stylists will still be confused but they won't tell you and that is when you end up with something that you weren't looking for. So making sure that you know what you're looking for and you describe it well will always be a much more foolproof plan of action on how you can get that perfect desired result. So that's all from me on the highlights today. I hope you guys learned a lot. I had fun teaching you and don't forget to follow me on Instagram, on Twitter, on TikTok, at BramondoNYC. Check out my haircare line, X-Mondo Hair. It is linked below and also on Instagram at X-MondoHair and that is all for today. Thank you so much for watching.  See you next time. Bye.


Hi everyone, I'm Becky Swan, athletic therapist for the Vancouver Police Department. You may recognize me from videos such as, the push-up is a moving plank, not a worm. Today we're going to talk about the run. You must run a mile and a half in less than 12 minutes. You can do all of it, half of it is mental. Short intervals are very important for speed development. After a warm-up, run for 30 seconds hard, then walk for 30 seconds to recover. Start with four reps and add another rep each time you do the workout. Long intervals help you increase your speed endurance. Run about an 80% effort for two minutes. Take a minute break and repeat. Start with four reps and add another rep each time. Time to practice a mile and a half run. After a warm-up, do the mile and a half, and meet while maintaining a steady pace. You should not be able to hold a conversation. If you can, you are not working hard enough. High-intensity interval training, HIIT, is a great cardio option, and it will really help for the polkaid and the run. Check in with us weekly for HIIT workouts. Thanks for stopping into this training session. Remember you have full control over this part of the application process. You train smart, you'll perform better. I look forward to seeing you on test day.


Probability theory is the branch of mathematics concerned with probability. Although there are several different probability interpretations, probability theory treats the concept in a rigorous mathematical manner by expressing it through a set of axioms. Typically these axioms formalize probability in terms of a probability space, which assigns a measure taking values between 0 and 1, termed the probability measure, to a set of outcomes called the sample space. Any specified subset of these outcomes is called an event. Central subjects in probability theory include discrete and continuous random variables, probability distributions, and stochastic processes, which provide mathematical abstractions of non-deterministic or uncertain processes or measured quantities that may either be single occurrences or evolve over time in a random fashion. Although it is not possible to perfectly predict random events, much can be said about their behavior. Two major results in probability theory describing such behavior are the law of large numbers and the central limit theorem. As a mathematical foundation for statistics, probability theory is essential to many human activities that involve quantitative analysis of data. Methods of probability theory also apply to descriptions of complex systems given only partial knowledge of their state, as in statistical mechanics. A great discovery of 20th century physics was the probabilistic nature of physical phenomena at atomic scales, described in quantum mechanics.


What's going on everyone Donnie here ripping a personal for Brian G Brian has a 21 22 leaf pearl multi sport Let us see what we got for you Right, that's the only sticker. I believe all right. We'll save the middle for last There we go, okay, we'll start on the left I guess can't wait to see how many names I'm a Prime is here Hey, you got a Holland That's a good start three of five on the auto that is That's the way to start rolling Holland on the first hit Pretty salad there. Let's see what we got next.  That's insane dude That is crazy. Oh my god All right, let's calm down let's calm down All right, that broke me a little bit. This is awesome though you're gonna be pulling Muhammad Ali Holy holland autos to start. This is crazy All right That was that was pretty good, I'll give you that I Don't know what that said at the bottom. I think it might have been an L But it could also have been a I I don't know All right next on the Kevin Garnett Uh jumbo patch five of five Nice patch there got next Okay, I'm a Muhammad Ali Three of five I guess this would be like a robe Yeah, that's what you were over something. That's crazy to Muhammad Ali It might say on the back exactly what it is sometimes it does it might just say fight warren rally pieces of game use memorabilia Doesn't specify but he trunks or a robe. I don't think it could be anything else. That's crazy, dude He wear white gloves. I don't know could have a dumb point. I mean true. That's it looks like a robe Yeah, that's not mean the fabric isn't like Super thick. Yeah That's crazy though. All right next We've got Joe Montana Well, that's pretty crazy. That's crazy on the letter patch letterman Five of Six I believe it is it's hard to tell the numbers are black along with the border. That's pretty cool On the front of this card piece of game use memorabilia and in Montana. That's sick. That's really cool It's the coolest Next we've got Joe Montana again Why right one out of six on the auto Montana Salad there. Yeah legal. That's kind of what I was why I said that Next we've got Kevin Kevin Burnett, dude I don't know why it's yeah, I don't know why it's the dupes, but Auto one of two on the Kevin Burnett auto You think this is just like another Muhammad probably coming up Just give me their Holland that that would make sense. That's the trend. We've got John L. Way on the QB bling auto 20 no 33 33 bookend Nice on the QB bling. Okay. Yeah, I see what you're talking about Supposed to get out. Okay. I was thinking about it. I wasn't sure I Moved it back and forth the entire break. Okay. I I've got Alan Iverson There we go. There's a different athlete on the patch auto two to four just two out of four not two to four Nice nice it there at the AI The answer From what I've heard Sam said Nobody's called that before he is the answer working here is the answer All right, can you confirm can't confirm You've got oh This is what's her name? Says it nod me Naomi Naomi that the only thing to be Naomi on the pearl. I thought this was some mail 7 to 10 Her last name Naomi Sock, Osaka. Yeah, so I was gonna guess nice on the pearl there and I guessing this is another cut. Yeah, it should be oh It's not it's not no different place Yeah, we got it weird we've got Signatures. Oh wow who we got here Jeff Bagwell Ivan Rodriguez Jose Konseca and Sammy Sosa on the quad auto One out of five that's pretty cool Right, that's pretty good. That's that's a pretty cool card though one of five What? Donny wait a minute We got Gary Sheffield David Justice Valimir Carrero senior in the mark grace that's a That's a Probably says on the front there's a signature signatures eight. I was just trying to think of the word for eight. Wow, okay Gotta read the card. Yeah, that's true Okay, well we've got eight autos on this car Wow All right, well Well, Brian that'll do it some pretty crazy hits out of that even though like we had a couple of dupes, but They had some really good hits Brian. We'll get these out to you. Thank you for the order, man