[MUSIC] Economy of mechanism is all about making sure that we do things in the simplest possible way. And there's really a number of reasons for this. One, we want to make our code more compact from a security perspective so it's easier for someone to see it, but also just from an overall design perspective. The less we have there, the less we have to maintain. So if we can get the same thing done with less, it often is helpful both from a security perspective and from a maintainability perspective. Okay, let's take a look at a specific example now with code. What we've got is an extension of the log in application that we talked about before, where we're going to create a log in activity, and allow a user to log into our app. Now for this one we're going to extend it with some new capabilities. So first, rather than just being able to log in, we're also going to give people the option to register, so if they don't have an account they can go and create one. And then we're going to go and give them the ability to reset their password, by clicking a forgot password button. That'll send a password reset link to their email address. Now in order to support this additional functionality we've created three buttons. So you can imagine on the home screen for this application, we have three separate buttons for log in, register, and forgot password. And then we've got two text fields that we're going to be using or edit text, that basically give us the ability for someone to enter their email address which is going to be their user ID. And then to enter their password, which we'll be using for authentication. We have quite a few options for how we could go and implement this functionality. Where depending on which button you click, a different thing happens. Either you're logged in in the application, you register a new account, or it sends you the forget password reset link. For this one, one example is we could go and we could directly take the login button and we could set the on click listener directly within, for example, the on create method. Or we could define this somewhere else, and then we could go and inside of here we could start the login process. That would be one style of doing this, and then we could do the same thing for each of the other buttons. And create on click listeners for them as well where we go and do registration or the password reset. And this is certainly one viable option or architectural choice we could make. And yet another one we could make, is we could go and actually make our activity implement the Button OnClick, whoops, our Button.OnClickListener. And if we did that, then we'd want to go through and implement the on-click method. And then if we took this route, what we would do is we'd go say LogInButton.setOnClickListener this we could set the registerButton.setOnClickListener this. And then we would go and set it for the forgotPasswordButton, as well. And then what would happen is, for any, if you click any of these buttons, it would all flow through this on click method. Now, the way that we were doing it before, we had a separate anonymous interclass that was the listener for each of these buttons. And depending on your code style, you might say, well, I prefer this method. This model where I'm going to route all of them through a single method, this unclick method. Some people may prefer the anonymous inner class approach. And I'm going to just show you an example with this specific application where there's a non preferrable architectural choice to make here. So one way to implement this on click method, we assume that we've decided to have a single on click method. Is we could say, we could go and check if the view equals a particular button. We could then say, else if = the registerButton. Do something then, and we could have separate login, logic, and register logic. We could do the same thing for password reset, just like we would've done on the anonymous in our classes. Now, a particular technique that I commonly use in my code when I have this sort of situation where I want to handle different, within a particular single method I want to dispatch two different sets of logic depending on some conditions or something that's passed in to as a parameter. There's a particular technique that I use a lot and in this case we're going to see it's actually a non ideal place to use that technique as I'm about to show you. So the technique that I like to use sometimes when I want to have a flexible method that can be extended like this. Is I'll go and create a private or public, you can do it different ways, we'll just make it public for this example. An interface like, we can call this Loginaction let’s say. The idea for this interface for login action, or we could call it execute is that we want to have a way of encapsulating the logic, the different pieces of logic that we would like to run in response to different buttons being clicked behind implementations of this interface. So what I can do is I can create this interface, and then I can go and I can create a map that holds mappings of these actions. In this case I actually need the key to be the view, and I can say LoginActions. And I can define a hash map that's going to hold these, so then what I would do is in my code up here I'm going to go and I'm going to say Logictions.put. And the idea is that I will put the button that's going to be the key, and then a new LoginAction, That I'm actually going to hold the logic for, for example logging in and then what I will do down in here, is I simplify this method by just being able to say LoginActions.get. Now I should check if there's actually a valid one bound to this and I can say execute. So as many times or as many different log in actions as I add I never have to go and change this on click method. And there's many cases where this type of refactoring of your code or this architectural approach to your code makes a lot of sense. Particularly for example if you want to be able to dynamically change what actions might get executed here. But in this example I've really only got three different things that I'm going to be doing, logging in, registering, and forgetting my password. And so if I go and I start adding this approach where I'm creating this map, I'm creating this separate interface, I'm starting to violate this economy of mechanism principle, because I'm adding complexity where I don't necessarily need it. And we're going to see how that's problematic in a minute, so this method, on the one hand, looks simpler. But if you actually look at all the things I'm adding, I'm starting to add a new interface that people are going to have to implement. I'm adding this HashMap that I have to worry about, I now have to implement that HashMap. So let's say that I want to go and do this for real, well, I gotta, for each of the log in actions, I gotta go and define them. So now I have to define one for the register button, and you can see quickly that this is starting to look less and less efficient. And more and more like the just creating why am I doing this, rather than going through and creating separate, Let me go ahead and, again, action rather than creating separate anonymous classes. Now to clean this up and make it look a little better, I might go and say well, I don't want to define all of this in the onCreate method. So I might go and move these and have like an createLoginAction. And I could go do something like this, although, And we could say, And then we could return the new login action that does login. It might begin to look more organized or fancy, we could create the register action and we would have registering here and we could go and create the ForgotPassword action. And then we would have the forgot password logic here. Now you can already see and I'm choosing this example because in this specific case it has security implementations and it's a clear violation of the economy of mechanism. But it does introduce flexibility, so we could go and without having to change our on click method we could easily extend. We could be able to allow other people to add login actions, and so it does create this sense of flexibility in the design. But we're clearly adding a lot of extra indirection here a lot of extra complexity in the designs. So, now we've added this log in action, we've added this map to hold all the log in actions. We would then need to go and create the map and initialize it with all the login actions. So we'd need to create the register action here, and the onCreate method. We'd need to create the forgot password action, and then we would set all the onClick listeners. Now I'm just going to go ahead and clean that up a little bit. So now assuming we went in and implemented all the logic for logging in and registering and sending a forgot password email. Then we would have this very clean and simple on click method. Now we might go and justify this to ourselves by saying, well we could do something like we could have a centralized way of logging, for example. When somebody's getting ready to click a button, and we could log what's going to get happen. We could look up the login action it's going to run or we could just have some centralize mechanism to do this and we might say well it's centralizes all these log in related actions. It allows us to have some type of observability of them within this method. To apply common authentication or other things, and it may seem like a good thing. But there's some simple problems that we have in this. Well one is that if you go and you're trying to audit this code now, and you want to know what's going to happen and first we've already got a bug in here. And this is a great example of why we're creating issues is if I look at this, I may not immediately jump out at me that I have an issue. But there is an issue, I'm actually looking up the action for the login button every time and executing it, despite what button somebody may press. So this is already creating a bug, this is actually supposed to be looking up the correct action based on the view that got clicked, or the button that got clicked. And if you're somebody who's coming from the outside, and you're trying to audit this from a security perspective, if you just look at this line and you say, well a button's going to be clicked, I know that. And I know that this is the click listener for it I can see that. I set the click listener for all these buttons to this method, and then, you come and you look at this it's really non obvious and intuitive what's going to happen. So the person who's auditing the security of this has to go back. They have to figure it out, okay, well what got put into the map Login button, well I've got this createLogin action, what does that return? And then they have to go down and find it down here. And what you end with is yes you've kind of pulled things apart, you've made it some extensibility happen. But the result of this is that we've sort of violated this economy of mechanism, and now we can't look at this and tell as easily if what's going to happen. Now this could get even worse, for example, if I went and I said, you know what I may want other people to be able to register login actions. So what if I went and added this great method and I could say, register login action, and I could define the view that's going to be clicked. And I could say register login action with this particular view, and this login action. And we could go and say LoginActions and we could place this action on the map and if we do this and we begin opening this up to the world, now we have a public mechanism. Sure we've added extensibility and configurability into our login activity, but what this also means is from a security perspective, it gets really hard to know what's going to happen when a particular button is clicked. So when you click the login actions button, or you click a login button and then it looks up the appropriate action to take from the login actions map. If you're auditing this for security, you don't know necessarily what's going to happen. For example, earlier I had this bug up here where I was referring to the log in button. Well what if I accidentally have this log in button down here in this registerLogiAaction method. And then now I've introduced a bug where it may not show up for a long time. And now I've got it right next to this so it may be obvious here. But lets move it down somewhere further in the file, and now I'm looking at this and I'm auditing this for security. And I say well yeah it's kind of complicated but I can see that their attaching login to login register action. Create registry action to register, I forgot password to forgot password. And you have this lurking bug that's left down here, and because you can't look at this and immediately see where this map is being populated. It means that you could have any class because we have this public method down here calling this method and creating this pollution and creating a possible security vulnerability by changing around how a login button behaves. Now I've made this example really sort of contrived in some ways by trying to directly connect it to the idea of authentication and login and different login buttons and suddenly having them re-mapped to different places. But this is exactly the type of thing that happens is you have something that appears simple, it seems like a good idea to refactor and have this map of log in actions. And then to add this flexibility, where you can go and create different login actions. But what you're doing is you're putting yourself farther and farther down this rabbit hole of by violating the economy of design principle we are making it harder and harder from a security prospective to know and be able to audit the security of our application. Also from an overall maintenance prospective in sustainability perspective of your app, yeah you've added extensibility but you've paid a price for that. And the price is is that you can go and make weird things happen like in this bug I've introduced down here. By remapping the login button's actions and you can make things really hard to track down. Now, we would have tests supporting this, we would have all kinds of things supporting this. But these are the type of bugs that can get you in trouble and typically they'll stem from, when you're trying to make things more complex than it needs to be. You're making the security harder to audit and you're also typically making it harder to maintain the application over time.