 Hello everyone. We are ready to talk about object orientation and everyone will present us some ideas about that. Thank you. Good morning everyone and a big thanks to the organisers who seem to be doing really well again this year. I sort of live a double life. In the Python world I am behind a project called Real. It's an experiment where we're trying to build a web framework where you can express your whole web application using Python only. No CSS and JavaScript and HTML and all that but rather words like Python classes like I have there on the screen. We can do really cool stuff already like this complicated example is all hidden behind one class. I'm not talking about that this year because I did last year and the link there at the bottom is to the talk of last year if you're interested go and check it out and help us. So rather than sticking to the same topic I thought I should pick something from my day job where I've spent a lot of time in the last decade sitting with programmers who are working on big systems systems that have grown for 10, 15 years and they struggle with these things. There was once a guy who struggled to add a button to a page for an entire week. So and my job there is to mentor these people and help them to improve the design of these things and to test them and stuff like that. One of the things that I realised is that there are very basic things about object orientation that are used in ways they weren't intended to and then they tend to make things very difficult for these people. And I always wonder about this and if you go and look on Google the way object orientation is introduced usually is by means of things like inheritance and encapsulation and all kinds of stuff that really those things are the tools. They are not the point. They are not what it's all about. So the stuff that I'm presenting today are very, very basic but I hope you've never seen it before. It actually comes out of books and things that were written in the 90s and before that. So first things first, object orientation really is not about object-oriented programming. There's a lot more to it. The whole idea is that you want to actually express how you understand the problem domain and build something that we call a conceptual model. Then you'll map it to a programming language, to code in some kind of programming language which does not need to be an object-oriented programming language. In fact some functional programming languages can work well too. But if you have an object-oriented programming languages then you will have some supporting mechanisms in there as Python gives us. So I'm going to focus a little bit more on the beginning of all of this, the conceptual models. I don't know if you know this old game. It was a very cool game. It's all about cause and effect. And I actually think that this is how a lot of people understand their programs. Something happens and then something else happens which triggers something else to happen, etc. Right? Programs are a little bit more complicated though because we can branch, we've got if statements, we've got loops and so on which means that the trace that you will follow through a program could be different each time. So that's a little bit more complicated to understand but you probably think that you do understand a program of this size. What if it's like a hundred lines of code? Can you still understand all of that and know what any change will affect elsewhere? You probably can, maybe. Maybe you're really smart. But the sort of systems on average that I tend to work with are more like a hundred and eighty thousand lines of code. And I can't understand them. So what does it take to understand a program like that? We have this thing in our heads that have evolved over millennia called an understanding that helps us to basically determine what we should care about, what represents danger, what represents opportunity. And this is sort of a built in feature that we have. And if I say what does it mean to understand a program, I'm really asking can we use this machinery that we already have to better manage programs? If you don't, then you have this maze of your code in your head, all of it because you need to know how to navigate from one place to the other and there's no meaning there. So let's talk about conceptual models, because understanding is all about conceptual models. If I have to explain something to you, I'll probably explain things in terms of concepts, right? So conceptual models are really all about concepts. And concepts are actually quite cool things. In this example here, I've got a concept chair in my head and you can see there that it applies to two of the objects in my awareness, two chairs over there. So what I can do now is if I know something about chairs, if I have some information about it, for example, that they're useful because you can stand on them if you want to change a light bulb, right? I can save that information only once and I know that it applies to both of those. If I didn't have this concept, I'd have to store that information twice. So it's a compression algorithm. But the really important thing about concepts also is that we give them meaning by means of giving them a definition. So I can define what a chair is and that definition helps me when something new comes into my awareness that I've never ever seen before. I can use this definition to decide, oh, but does this new thing actually, does one of my concepts actually apply to this new thing? And if it does, everything that I've learned about chairs in my entire life, all of a sudden become useful in connection with this new thing. That's really actually quite amazing. From a mathematical point of view, though, we model concepts as sets. So a chair, the concept chair can be the set of all chairs and so with desks as well. And this provides the foundation for everything object oriented because everything that you know about set theory and mathematics also can help you to reason about stuff. One important thing, concepts in my head aren't just a list, an unstructured list of concepts. They actually have an intricate structure. And one of the things that give rise to this structure is that we also have subsets here. So an office chair in this example also confirms to the definition of chair. But maybe we can say a little bit more about office chairs. It's a bit of a more specialized kind of concept, right? So this is the one thing that gives rise to structure. The other thing is that I can actually connect objects from one set to objects in another set. In this case, I drew some lines there to show that one chair is assigned to a particular desk and another chair is assigned to another desk. The sort of picture should be familiar to you as well if you think of mappings and relations and so on in mathematics. But there's another way also to look at this. If you take all of that stuff away and you just keep the connections, there are two of them. So they can be a set as well. So this set of connections is also a concept. And this relation is the concept of assignment in this particular example. Before I move on just a quick detour, we like to specify a little bit more about relations. And we call that multiplicity. So we would like to always say, well, in this particular example, more than one chair can be assigned to the same desk, but not the other way around, right? But it becomes a bit complicated to talk about these things and to denote them using Venn diagrams, right? So in the 90s, before then, I think a lot of people came up with a lot of notations for dealing with this stuff. And finally, standardized on UML, which you probably know. And this exact picture that I have here is the same as you saw in the previous one. And I guess you all must know UML, but I'd like you to look at it possibly with different eyes, thinking that chair here is a set of which office chairs form a subset that I can say something more about, which is, oh, they could be assigned to desks. But we don't actually program with chairs and cars and stuff like that, right? So it also isn't about physical objects. That's not what object orientation is about. It's about concepts. And most concepts are actually intangible things because they really just exist in our heads. And this is a real world example from the investment industry. So there could be a concept called investment in instrument, which is something I can buy in the hope that it'll become worth more over time, right? A subset of those things are called unit trusts. They work in a particular way. And they're slightly different to other investment in the instruments, right? And I can have something like a portfolio. That's a way for me to keep track of all the things that I own. None of these things really exist in the real world. They're all intangible and only exist in our heads. And we keep inventing these things as we go on. Something you need to know, though, is that our heads are very flexible. For example, sets can overlap. So I can be both a person and an investor at the same time. Actually, it gets worse because how I am classified can change over time. So I can be a person and eventually also be an employee and at some stage also become an investor. And then maybe stop being an employee again. That's how we think about the world. It's time for me to change terminology, though, because no one really talks about concepts, even though all of this stuff is based on concepts and the definitions that I've talked about up to now. But the word concept is merely a label that I've attached to concept so that I can talk to you and explain to you the concept of a concept. Typically, in OO, of course, you can attach more than one label to a concept. And in OO, the label type is more commonly attached to what I've explained right now. Those, of course, are synonyms. So from now on I'm going to try and switch terminology, but please don't forget concept. Things get interesting only when we actually make changes to objects. And that is where operations come in. And operation is also a concept. It is something, its definition basically says what it is that you want to happen to a number of objects. So it operates on a number of objects. In this particular example, load prices is something that can create a bunch of prices and attach them to unit trusts based on the data in a price file. Say, please note that I'm not saying how you do this. There's no algorithm here or anything. This is just what it means. And that's what concepts are all about. They import meaning, right? At the end of the day, though, we also need implementations for these things. And this is where methods come in. Operations are implemented by methods and an operation can be implemented by many methods because there's many different ways to do something, right? The same thing. A quick summary then, what we've covered so far. So let's say, just for argument's sake, that we will view anything we'll call any thing in the world an object. A subset of those things are called types or concepts. Types are special because they can have subtypes and they classify other objects. A special kind of type is a relation and relations link objects together, right? And another special kind of type is an operation which operates on a bunch of objects and gets implemented by a number of different methods. You can sit with a head full of concepts. How does that help you? Because you still have this spaghetti bowl of code lying somewhere. What's the point? How does this help us? Well, what you can do is you can forcibly structure your code in a way that conforms to the structure of the concept in your head. In this particular example, if you take the blue block there, you can sort of block out a lot of detail and say, okay, well, this is a method. And it's a method that has to do with parsing CSV files, right? You can block out the red block there and say, well, this is also a method. It's the method that I use to parse XML files. You can actually put them together and block a bigger piece out of detail and just say, okay, this has to do with the operation of parsing files. And if you take this to its logical extreme, you end up in a place where you can really just think of your code in terms of the concepts that are in your head. Which means that all of that detail that sits in that code, you can forget about it because you can just focus on what you really want to. For example, I can explain to you that a price file has a particular file format. Tomorrow, perhaps, it's interesting to know that there are two kinds of file formats. The one is Excel and the other one is CSV, right? And I can know absolutely nothing or need to know absolutely nothing about Excel if I just want to look at the method for parsing CSV files. So where does Python really come into all of this? There are basically two kinds of object-oriented languages. The one sort is prototype-based. That's what JavaScript does. Python conforms to the classical object-oriented programming languages. So I'm going to quickly run through that just to explain how what I've talked about up to now actually maps to Python. Well, we need some way of actually saying, expressing the types in our head in Python. And this is where classes come in. But please note that classes are much more restrictive thing than a type, which is a more theoretical thing. Classes are like cookie-cutters. You can create instances and all those instances are the instances that are classified by that class or that that class applies to. You can't change the class of an instance. There are a couple of restrictions like that. Just to show you, I'm not talking nonsense, there's a doc test to show that it works. For relationships, we've got simply something equally simple. We don't have anything like a relationship that can actually attach two different things. We just have a one-way pointer and that's an attribute. So if a portfolio has an owner attribute, it can point to another object somewhere else. And that's all we have. So anything we want to do with relationships has to be built on top of this. And once again, just to show you that it actually works. Methods and operations are interesting, because they're actually both present in Python. But operations aren't there explicitly. They're sort of there in ghost form and I'll talk about that a little bit later. But you know that a method is basically just a function in Python, except for the one other strange restriction and that's that the method has to belong to a clause. That's also something that theory doesn't actually expect. But to make things work in the real world of computers, we have to live with this limitation. Obviously, the other interesting thing that Python does is it allows you to... It has a little bit of a trick. If a method is a function, you could call it like I wrote there, you could call it on the actual clause and pass the instance in, right? But Python just has a little bit of syntactic sugar, which has an important role to play so that we can call this method on the actual object, right? I'll talk about that in a moment again. Just for completeness, I had to put the slide in here. Otherwise, the other examples won't work, so we do initialize instances, right? But more importantly, subtyping. And this is probably one of the most misused things in the world. So to be able to express this idea of subtyping, we have inheritance. What happens in Python, of course, when you create a clause that inherits from another one is that this clause will also have the methods of its superclasses. In other words, people think that it's about reusing the code. It's actually not. It's an expression of your intent. It says, oh, but a unit trust fund actually is a concept in my head which conforms to the definition of an investment instrument. And just again, a doc test to show you that it works. Let's get back to operations, though. Let's say I've got this scenario where I've got two different file formats and I've got an operation parse. Now remember an operation is a concept, so it's got a definition. The definition of parse here perhaps means that a parse operates on two things, a file format and a file. And it will return to me the data that's in that file, maybe line by line, for example. What we would do in Python is we would actually write two different methods. We'll have a parse method on CSV file format that has a particular implementation and a totally different implementation on the Excel file format. The way Python actually knows that these things are different implementations of the same operation is because we called them, we gave them the same name. It allows us to write code like this. Assume that a price file has a file format, then you can say for line in price file dot format dot parse, this particular file, right? In other words, when you look at this code and when you have to understand this code, you can make use of this concept of parsing files without having to know the details of how it's going to work. You don't even have to know that there are many file formats. You just must understand the definition of the concept parse. That's all. If we didn't have that, you have to write something like this and there are a lot of things wrong with this. Just a few quick words on design. When you think about a conceptual model, when you discuss things and debate things with a business person, for example, you live in this world where you could come up with a model like this, a person that can become an employee and eventually not be one anymore, et cetera. The problem with this is that it's not implementable. We understand it pretty well, but we can't implement it. This is what design is all about. You can, though, take that design and come up with a different understanding that you also understand equally well, but it's implementable. In this particular case, we decided to think about it a little differently and say, well, perhaps a person can have roles and there are two types of roles, employee and investor, and I can add roles and take roles away during the lifetime of a person. This gets the same job done, but it's implementable. That's what design is all about. Of course, design is a difficult thing and I would never be able to make statements about it quickly and easily, but you do get worse design and better design. Just to give you a feel for why this is important, I've got this picture up. This is actually a real world example from one of my clients who would like to stay anonymous. It has been reverse engineered from actual code. It's got to do with how commissions are being calculated in an insurance company. I would never be able to explain to you how this company thinks about calculating commissions using this, because most of the things on here really don't impart any meaning to me at all. They are merely there because someone needed something to put a method on and didn't quite know what to call it, right? I sat with this exact stuff, went through this code. I can't remember. I think it took me about two weeks and came up with this. Can you see the contrast? I can actually use this. I can use this to explain something to you. I can say, okay, when we do a quote, we quote for particular scenarios and a quote scenario is composed of a bunch of benefits. I can say that if we work out commission, then these benefits are bundled together because commission is worked out differently for different bundles. I can also say that a scenario is for a particular product and that each product has its own commission scale. There you know a lot more already and you have an index that actually makes sense, an index that matches your understanding that you can use to navigate this code. One other quick example just because people love to use inheritance in the wrong way. I have another client. They've got a system that has this class called object table. Now an object table is something that just displays a table on the screen for you in which each row is an object and each column is an attribute of that object. At some stage they have the need that people would have to filter this thing. For example, maybe you just want to see the unit trusts that are actually active. Then they created object table with filter. A little bit later on someone had the need that you must also be able to filter these things by date and so they added object table by date. If you argue with someone about this it's very difficult to say that these things aren't concepts. They are concepts. People with red shirt is also a concept, right? But is it a useful one? Does it say a lot about what's going on here? Or is it just an abuse of inheritance to reuse code? There are other ways of doing this. For example, you could say let's change object table so that it actually has filters and we introduce this new concept called filter. Then when we create an object table we can decide if we wanted to have filters or not and add the right ones. Or you could say let's say we've got three objects, three kinds of things here, report. So let's say an object table is just a simple table that displays stuff in a table. But a report is something that has filters and an object table and it uses its filters to decide what gets displayed in the object table. So there are lots of ways you can rig these things and if you don't actually rig them to import meaning that's when you run into problems. And that's what OO is all about. I prepared both of this talk from a book that is out of print. You will still find second hand copies of it on Amazon. I think it's that book by James Martin and James O'Dell. I highly recommend it. If you want to know about good and bad design, work for many years with the refactoring book next to your side. If you want to chat about this stuff you welcome to email me. You can even use our email, our mailing list. And then there's a link to all the slides. Thank you. Thank you very much. Any questions? About object oriented programming? Well, yeah, Rani? Yeah, thanks for the talk. That was great. If you were choosing a programming language to amplify this for students, would Python be the best choice? I don't know about best. I really do like Python. I have to admit that because I have to make money also I sometimes work with clients who do Java. One nice thing about Java is that the refactoring tools work really, really well. And refactoring is a good way to learn about design because you see what's bad and you realize what can be better. And to see the transformation in front of your eyes is really a good thing. So I think it's a pity we can actually do better. The very first person who wrote these thesis on refactoring did it in small talk with the same limitations we have in Python. But I think even despite that, I probably would still choose Python just because there's a lot less unnecessary fluff. And also because Python allows you to not always do everything in classes and methods. If you just need a little function somewhere, you can stick it in there. And I think that helps as well. Any questions? So Java, for example, offers you a lot of great tools for not only refactoring but expressing concepts. And what I especially like about Java is the ability to define abstract classes and interfaces. Now, I know that Python, for example, has introduced abstract based classes, which in my opinion is a really valuable tool but only during runtime. Because the implementation of ABCs is only validated during runtime. So I was wondering, is there any tool that you can recommend to get a more to get a better understanding of the way classes interact even before you actually run the code in Python? I'm sorry, I'm not aware of anything. It's actually something I would really, really like. I think the fact that Python is a dynamic language is something that means we have to deal with these things differently. And how it was done before, long before in other languages, is to say, well, if you can use the trace functionalities and things to, if you run your tests, collect data about what calls what, etc. Then that gives you a lot of that static compile time information that you otherwise don't have in Python. And I actually really would love to see a tool that does that. And so that refactoring tools can be based off of that. But I'm not aware of anything like that. Did you ever run into the problem that you had, that you had a concept which you could not realize with the programming language you chose and had to hack the concept or hack the programming language to make it actually work? I'm going to have to say no, but I probably cheated here and there. You know, nothing is perfect and the aim of this is not to have it perfect. The aim of it is just to help you have a good map of your code that works well with our how our heads work. And if you think about it, very, very complicated things are expressed in terms of concepts if you think about Fourier transforms, for example. It's a concept. But all right, no, I haven't. But sometimes you cheat because remember classes aren't the only things that are concepts here. The relationships are also concepts. The operations are also concepts. And sometimes you express a certain bit of information about something by adding a decorator to a method or whatever. I think that we have enough play here to deal with everything that we need to deal. So what's your opinion about dog typing? Do you think that's a good design decision or something? I actually think it works quite well. I think that there are a lot of problems that Java, for example, run into with its interfaces because people create a lot of classes that don't really explain much. They are very functional in name, like, sortable. That doesn't tell me much. It just gives me the mechanics of making sure that this thing will work with other things. So, yeah, I would actually prefer dog typing over using abstract based classes, for example, in most cases. Thank you. We have one question from online. Translate it from online. Craig Sparks asks, do students fresh out of university and distance, object oriented and better than all the developers to your mind? And do students still get taught object oriented at universities? I don't know. I don't know. This particular subject material, which is actually very theoretical, just gives you a different point of view on things, right? But if I search on Google, I get encapsulation in irritants, information hiding. It's almost like teaching someone how to drive a car by explaining how the car works. So, I don't actually know. I don't have enough exposure to know what's being taught in universities currently, but my feeling from where I stand is I miss these things. I don't see them around. When you have a lot of parent classes when you're doing subtyping and whatnot, did you find a tool that could really easily debug like if you have the same method in multiple parent classes? Sometimes you can get a conflict of methods. Did you have a founded tool that could easily debug and see what is the order of execution? Because sometimes it's not really what you would want. Are you talking about having several super classes? Yes, if you have like one child built up from multiple, like with mixings or something. Like with mixings. Sometimes you get a conflict and you try to do your best to really separate this and not have these conflicts, but life happens. You know, I try to avoid mixings and multiple inheritance. So actually in our code base we have a couple of mixings in the test code, but I have come up with a plan to change that and I can't wait to be able to implement it. I think that multiple inheritance doesn't really add much to the picture. Usually you can actually express things differently by composing rather than inheriting, for example. So I haven't been searching for tools like that because I tried just not to do it at all. It's actually a comment for your question. I don't know if this is what you're looking for, but I think that in Python 3 and I don't know if in Python 2 you actually have this magic parameter the object method resolution order, yeah, MRO. Yeah, I'm telling you exactly. Under MRO, you have this and you can inspect it in a repel session actually with your objects. Just a brief other question. How about functional programming as an alternative because you've got closures and functions could be used rather than objects? Well, think about a function. A function can just be an implementation of an operation, right? And if you work with method, I don't know a lot of functional languages, but in Haskell for example, you can state that what types a function is actually applicable to and you can have multiple functions with the same name but that expect different types. So Haskell can actually also choose at runtime which actual implementation it will use. So I think that the same concepts apply. Yeah, I think so too. Yeah, we have five minutes. Feel free to ask questions. Well, if there are no questions then I think that we could thanks Ivan for a great presentation. Thank you.