 Welcome to Agile Roots 2010, sponsored by Version 1, Raleigh Software, Virio, Amirisys, Agile Alliance and Xmission Internet. Expressing Design and Code, Architecturally Evident Coding Patterns by Dr. George Fairbanks. I'm going to talk today about Expressing Design and Code, which is very similar to who I talked with just in here recently. His focus was on how much design should you do. I'm actually going to talk about in the code how to express the design you've got. I have a consulting training company on software architecture called Rhino Research. Okay, so who am I? I have a PhD in software engineering. I did a thesis on framework and static analysis, which I absolutely love. So a few love frameworks come talking afterwards. I engage in committees and do reviews for this stuff. But what you guys care about probably is on the right. I'm an old-time kind of agile guy. I started doing a small talk project, actually back in 95 and 96. We convinced and moved from eight months to two-week iterations. Everyone was very stressed about this thing, but after a month of that, they were delighted, as you might imagine. In 98, I started doing tests for development and recently I've just written a book called Just Enough Software Architecture, which until Jim Copeland wrote his book, which I think is due out like next month or something, I was going to say this is the first book to treat software architecture and agile as peers, as reasonable things. You guys have probably seen other architecture books say something like, use iteration zero, spend six months and do all your architecture or something ridiculous like that. This book hopefully doesn't do that. Okay, so I'm only at a 45-minute talk, very short. So what I'm going to try and do... Does anyone remember how many patterns were in the Design Patterns book? 23. Okay, so I'm going to try and do 21 in 45 minutes. So it's impossible, right? Can anyone do voices? Can anyone do Ed in a mold and do her quote here? You guys remember this? She was like, it's impossible. I'm not too busy here. So we're going to try. We're going to run through here. But do you know the story behind that? It was Brad Bird that actually did that. So he was looking for somebody to do this. I think it was, I can't remember the name. Anyway, female comic. And she goes, no, I think he nailed it already. So he just did it himself. So the question I have for you guys is, I'm coming in here like a lion into the sheep's den or something here, talking about architecture. And my question for you guys is, agile and software architecture, are these things anathema or are these two things compatible? Okay, so I have one shaking hand, shaking hand. I think that means good, that they're compatible. Anybody else have concerns? Absolutely. Okay, so good. I think we've selected the right population here. Everyone else has another talk. What is this idiot talking about? So I happen to believe that they are. However, you can sort of, by reading between the lines, there's a lot of rhetoric around agile and people tend to de-emphasize software architecture because it comes a lot of back here. However, let me do two slides to set the tone here. The first question I have for you guys is, why has Toyota built good cars? And I ask, I give you a choice. Is it because they do lean development or because they have automotive excellence in engineering? Which one is it? Yeah. Why does it have to be one? Exactly, it's a false choice that you see through all my subterfuge, right? I mean, it's terrible. You guys are too quick. So one conclusion you could draw is that lean development is what makes them Toyota, okay? But if I did lean development, I would make terrible cars because I know nothing about how to make cars, okay? So you really have to have both. So my second question to you guys is, where does your design knowledge come from? You sit down, you do some para-programming, you're going to build something, you've got to try to use your stories. Your design knowledge, does it come from, in France, from having done lots of projects and you can get to be a good developer? Or does it come from books? Did you read books on how to be a good designer? Which one did you do? Both. And obviously the answer is both, okay? Now, agile brings a whole bunch of technical practices with it, right? Test driven design has been like the biggest revelation for a long time, testing was unsexy. But now everybody does it, everyone is reasonable. It's great. We do para-programming and so forth. But that doesn't mean that there aren't other technical practices that we need to master, okay? And so I was anticipating, perhaps I'd have to sway the crowd more, but it looks like you guys are already with me. So the way I think about this, and I try to explain this to people, is that although architecture comes with a lot of baggage, we need to disentangle three different things. The first one is the role of an architect. And that's a choice you can make inside of an organization. You can have an architect or not. You can have a head designer who could not have a head designer. You could have a team of developers. Second thing is the process you go through called architecting, or actually you could use scrums or you could use any other process in here. And then the third thing is the architectures that isn't artifacting, okay? Now, I ask you a question. When you look at a car is driving along the road, do you have any idea what roles they have inside their company or what sort of process they were following to make the car? No. No, but can you tell me if it's a hybrid or if it's internal combustion or if it's a truck platform or any of that sort of stuff? Yeah, I mean there's technical things about it that you can inspect the artifact, okay? The aircase was a car. At the aircase, it's a website or it's a controller for a thermostat or something. But the point is that my emphasis here is to talk about this third thing. Again, this is meant to be a bridge which happened to fall down. So we want to use proper techniques for building so we make sure things don't fall down. And that guy's supposed to be scary architecture. So we have to do that. My belief here is we can switch this around a little bit instead of architects, architecting architectures. It has agile-less, addling architectures. So there's no reason we can't have the agile software development roles, the agile processes, and we are still talking about the same technical features of the code. So I would say that architecture needs agile. Well, you guys can agree my little joke here says absolutely illiterate. Anyway. Second time. Second time. You have to read it because you're in the front, yeah? Yeah, all the way at the top too. And answer. And answer. Okay. Well, my name doesn't begin with A. Okay. So here's the basic structure of the talk. We just talked about some of the setup here. We're going to talk next about what the heck is design intent. We're going to then have to do a little bit of background because not everybody's on the same page. When I say architecture, you may think something different. So I'm going to give you what I'm going to talk about here, my background in this. And then finally, the bulk of the talk is going to be down here on all those patterns for coding design. Okay. So sometimes people like to say use the code loop, right? Use the source loop, right? Have you heard this expression? Right? Because all the truth lives in the code. And I'm going to argue that all the truth does not live in the code, okay? So this is a thing from Wikipedia on code optimization. Apparently they took this on the left and turned it into that on the right and there are equivalents, right? They're mathematically equivalent. You can function the terms one to the other. And you can make the argument that the one on the right is not the one that you want to maintain, right? Because the one on the left has a whole bunch of things inside of it that are embedded in it in terms of its structure and its naming and so forth that allow us with our code arrays because that's just the... We are humans, right? We're not the compiler. We're not the CPU. We can read this and understand this better and therefore be able to maintain it better and find bugs in it and all the good things we'd like to do. And even then, this doesn't represent all the knowledge. This program happens to compute crimes and presumably it relies upon some principles of math that allow this algorithm to work, which, you know, aren't expressed better, okay? I actually took a course a million years ago at the University of North Carolina on software engineering. For some reason, this guy thought the course should be about proving programs to be correct. And all the programs you guys have ever done is you gotta go dot it on each line and you have to prove some predicates are true and so forth. When you go through a loop, you have to have a loop invariant. And all these loop invariants happen to rely upon some proof or some property of pure math theory that I had never taken. So, like, this infinite series converges to pi. And I was like, well, no wonder no one's not proving correct. No one's proving programs correctly more because you have to have these weird mathematical proofs. I bet nobody here, you're right. It's also the proofs for the pilot. Yeah, oh yeah. How does the quality assurance system work? Have they proved there any code? Yeah, they've been proved for the pilot. Yeah. My point is that it is merely that there's a lot of information you have as a designer that isn't gonna be expressed here in the source code. Even if you put comments in, even if you do whatever else, okay? However, so the point is the solution is not the design effect. This is the program code as the solution and it doesn't necessarily represent all the design effect. However, it's something that we wanna get closer to. So I'm gonna call the design intent. Is the system developer's understanding and desires with respect to how the system should be and how it should evolve over time. And what happens is we lose the design intent between when we're sitting here chatting and we're just catching on whiteboards and stuff and then when we go and I should write down some Java code or some Java script or whatever it is, we lose the design intent. And it's the difference between what was understood when the program was written compared to when it's evident from reading the program. You guys probably took a software engineering class as an undergraduate. Do you have that job where one person writes a spec and the other person has to implement it kind of thing? Yeah, yeah. And so now that you're grown up and you get to be paid to do the same thing, some of the things happen, which is that one person writes a program, the other person has to read through it and figure out what the heck is going on, okay? And a lot of the actual practices in terms of naming deal with how can we make sure that we can convey that to somebody else without writing, you know, Illuminous comments and big design documents and so forth. But I'm still gonna assert that you can't encode all the design intent because it's a common misconception and we can still do better. So your first answer hopefully is, wait a second George, why can't we encode all the design intent? Any thoughts here? Yeah. You're probably gonna spend more time documenting the code than you would writing, testing, and running it. I agree with that, it's true. But can we think of any reason why like if I had an infinite amount of time, I couldn't express everything otherwise? Yeah. It tends not to express concepts that are from the domain. Yes, that is troublesome. Yes, anything else? So I think the intent that any design intent that you can provide is at best fixed to the moment in time when you wrote it. And as soon as somebody comes and looks at it, that's all gonna change. You know, a lot of the ideas that you had in there are completely invalid. And the best they can do is figure out how do I take it from this intent to this new instruction? Okay, I agree with everything everybody said. So far, I have one like, you know when there's like this killing stroke that like once you hear this argument, you're like, oh, of course, I won't even try anymore. Okay, so this is one, this is my idea of the killing stroke. In your program, you can say what the program should do, right? You say, do these things, dot, dot, dot. It's an imperative language, it's an O language, it's a functional language. Somehow you're still giving instructions to the computer. When's the last time you wrote an instruction what the computer is not allowed to do? You can't, right? Because you have a language which is geared towards encoding solution. It's not geared towards encoding non-solutions. But do you ever want to tell the program in terms of design intent what not to do? Yeah. Yeah, like what? Like to allow those. Yeah, yeah. Give me an example for that. Yeah. I would tend to capture that design intent in terms of a test that was to fail. Yeah, we can get into that, but let's count that as extra linguistic, right? The tester over the side. But okay, so here's an example. If you want to have your cache be coherent, you can't circumvent the cache, right? If you circumvent the cache, the cache has stale data in it and you go grab things out, you're grabbing the wrong thing, right? So you say, if this cache is ever going to work, somebody can't be going to grab data and invalidate the cache, okay? I mean, simple stuff like that. That's your design intent. It's like, you know, everybody has to go through the cache, otherwise things don't work right. Right? So there's these two guys, Rick Kaisman and Amnon Eaton who came up with these two words which aren't intuitive to me, but this is what the language are using, intentional and extensional. And they said intentional elements are once they're universally quantified, like all filters can communicate neopipes. And extensional ones are ones that are enumerated or named and so forth and say the system is composed of modules A, B, and C. So when you write in your programming language, you're saying here's module A, here's module B, here's module C, okay? Now, sometimes you have the intentional rules that apply to all the extensional things you define. So if you say, you know, I have got a filter A, filter B, filter C, and you say all those filters are going to communicate via pipes and only via pipes. That means that somebody can't come along and evolve the program to make them communicate via events or method calls or something else, okay? And so if you look at these architectural model elements and I'm going to review these a little bit, you can say the extensional things are things like modules, components, connectors, ports, and component assemblies. And even if you say my language can't let me define a connector, right? I have to define that as a class or something. When I look at the code, I can still see a correspondence between this was my design, I sketched these things on the board or chatted with a colleague about them. And I look in the code and I see that that's just a zoomed out version of this detail thing. I see the code. However, there are a bunch of intentional things. So these are including styles which are sort of like architectural patterns, right? Invariance, responsibility allocations, design decisions, rationales, protocols, quality attributes like must be fast and models, all these sort of things you're going to have your code conform to those like you were talking about with the test, right? But you can't generally express them directly in the code, right? You can't say this line of code, you know, executes within 40 milliseconds otherwise it causes the display to go boogie, right? You can't say that in code, right? You just have to admit your code that respects it, okay? So that's the problem. Here's the exact problem is that what we're saying here is that sooner or later no matter how good the job you do trying to express your design intent you're going to end up with some things that are hard to express in the solution language in the programming language, okay? So we've got this problem but we can do good things about it. So let me ask you a question here. Which of these two, number one, number two is the OO design? The first one has a pointer to a destruct and the loop bar from the second has airplanes, routes and landings. Two. Yes, thank you very much. Now, why is it that number one is not the OO one? Okay, so why does the second one describe object? Why don't you think those are route airplanes? Well, they're abstractions. There's abstractions in the first one. Yeah, very low, very, very low. Well, okay, so I already gave away the answer here in the second line here is that OO designs encode the domain, right? So you make, this was the observation with Simula back in 1967. They were writing the simulation that Cameron wrote was for and after a while they realized, hey, wait a second, why don't we just write a language where we can directly express the things we're trying to simulate in the language and then Alan Kay picked up on it and did small talk and the whole thing and he said, what you really want to do is you want to have objects or classes that represent the things in your domain. So what you did was you expressed the domain inside the code and we do this with lots of different ways. Variable names, class names, method names and to some extent, object responsibilities. I mean, airplanes sort of act like planes from the real world and then they can take off the land and so forth. But in other ways, airplanes do, airplanes encode do different things than airplanes in the real world. Like you can say airplane dot persist whereas the real airplanes don't persist, right? You can serialize your airplane into the air or you can serialize it into the air. So, okay, but the point is that we've been doing this expressing the expression of our design intent in the code for a long time. I'm saying it's entrenched in the OOA of thinking about things. By the way, number one, I'm not saying is a bad design, right? If you're writing a device, remember, this is probably the most effective way to do it is to have pointers to blocks and stuff and you shove these things around. Okay, so I'm going to show you my second favorite pattern book in the entire world. Everyone should read this book. It's an oldie but a goodie. It's right there on the screen too. This is Kent Beck, Small Talk Best Practice Patterns. A friend of mine said, I'm going to take your book and rewrite it as a job of best practice patterns. Okay, I can just change all the small talking examples to a job of 1997. Wonderful book. In fact, I was having a conversation about this book last night with an old friend. I happened to bump into him here and he goes, oh, yeah, yeah, yeah. There's this great pattern in here. I think I can find it. And he tells me what it is and I say, yeah, it's the page that's turned down, right? It's one page turned down. And here's the quote. It's from this pattern called the Intention Revealing Message, i.e. Methodic Messages in Small Talk. What's going on in communication? Intention Revealing Messages are the most extreme case of writing careers instead of the computer. As far as the computer is concerned, both versions are fine. The one that separates intention, what you want done from implementation, how it's done, communicates better to a person, right? And everyone would agree with this. I mean, this is why we call methods, you know, total or a calculate total expenses instead of t or x. Or someone was telling me about code that they saw recently that was so horrendous that he named all the methods after movie stars. And so to get real stuff done, you called Marilyn Monroe. I mean, Kaz and Gene Kelly is a parameter or something. It's never just we'll never do that because we're so used to embedding meaning into the method. Great. So, I've generalized this into something I call the model in code principle. Expressing models in code helps comprehension and involveability. And so far we've seen the domain of the code. There's the standard OO programming style which is coming from motion for many other people where your class is mirror of the things of the domain. Or there's a stronger version that Eric Evans actually advocates that you can do domain driven design. And there's actually a chunk of your code that operates in the same way that's analogous to how your domain works. And I would say from an academic perspective we can't quantitatively say, yes, this stuff does work. There's no data out there on this. However, the fact that we are all doing it and we all believe it's true is probably good and I believe it's going to need help. I mean, it's angelic. But notice, as soon as we try to express our understanding of the domain in the code, we have just opened the door to technical debt. Technical debt could be defined as the difference between how I believe things work and how the code does work. And so by trying to make them match up, you open the door to them, not them matching up. So it's both a blessing and a curse because the debt is sort of inevitable but now you can see it. Because you look at this code and you say, this airplane is, what is something airplanes don't quite do, right? It's taxiing over grass or something like that. Airplanes don't taxi on grass. They only taxi on the paper or something like that. So the idea down here is that we can put the architecture models in the code, okay? And you might say, I don't build models. I'm going to have to list. I would say, haha, but you still have them in your head. So I need to talk to you a little bit about what I need my architecture models. There's examples I'm going to be going through in the last section here on petrified time. This is normally a one hour talk and I'm trying to do it 45 minutes. Am I talking too fast? Okay, so those evil bad software engineering guys. By the way, there's two categories of evil bad software engineering guys. There's the process guys who you probably don't agree with. Those are the lots home pre-camp. And then there's the really not evil at all guys. The Paul Clements and Len Bass kind of crowd. They write the architecture books. And this is their definition from the new version of the documenting software architecture book coming out this year. The software architecture of a computing system is the set of structures needed to reason about the system which comprises the elements, relations, and properties of both. I haven't liked this definition better than some of the competing ones who say things like architecture is the stuff that's hard to change later because it enumerates what the things are because my boss is hard to change later. But I can't, you know, that isn't part of the architecture, right? So I would say that every system has an architecture because you can look back on it like we were talking about with the cars on the street, you can look back on it and see what it is, okay? Even if you didn't know what you were going to, it doesn't imply you have to plan up front to reference your system. You may evolve into a reference system but it still has that architecture. Architects pay a lot of attention to quasi-existence. These are also called extra functional requirements. They're sort of badly called non-functional requirements. If I had a drinking fountain that had a sign on it that said non-functional, what would you think? Right, exactly. So let's use extra functional instead of non-functional. But it's almost impossible to improve that. Or sometimes called the EDC. Things like latency, modifiability, usability, testability. And this is an open-ended set. You can create new quality attributes any time you want. So the architecture you choose or evolve into influences the system's quality attributes, okay? Now, who's used Skype before? Almost everyone, I see. Or some pretty accurate, okay. Can anyone imagine Skype being written as a three-tier system? Yeah, maybe. But it wouldn't be quite the same, right? Because like the main Skype server crashes then nobody gets to run Skype, right? But the neat thing about Skype is that it's completely, it's reliant, you know, because it's peer-to-peer. And like anybody who turns on their computer gets to be joining into the mesh, okay? Do you guys know what the map-reduced pattern is? This is a kind of architecture that you can use for operating on enormous internet scale, as they say, size data. And you can sort of chop it up, process it incrementally and then recombine it so that you can create, for example, the Google index, okay? And since I'm in here and I have your attention for a moment, let me just do one last thing, which is to say everyone always wants to draw their architecture as a layer diagram, okay? Have you guys seen this? Where someone tries to force fit their architecture to a layer diagram? Not every architecture is a layer diagram, right? You can build a perfectly good system that doesn't conform to a series of layers, okay? But everyone always feels like they have their layers and they have these bars on the side and then they have some extra things because, you know, it doesn't line up in this stack like they want to. That kind of is one of the patterns, by the way. Okay. Now, the standard way of talking about software architectures at least from the architecture community is as a series of views. You might remember Philippe Prouchen's four plus one architecture views paper from a million years ago. And he said, you can talk about these standard perspectives on the software system. The three primary, what they call view types these days are the module, the runtime, and allocation. And this is a problem that's as old as the hills. And I want to remember the go-to considered harmful paper. Right? Okay. So the argument in the go-to considered harmful paper was we should use structured programming. Why? Well, programmers being human have a hard time moving from a fixed set of statements to what's going to happen at runtime. In other words, he was just thinking about like a method with, you know, go-tos and so forth in it. And you're trying to imagine what the sequence of operations are going to be at runtime. It's hard to make the jump between the module what we would now call module view type and the runtime. In architecture, we think more about if I run this program what sort of data structures and components and so forth pop up at runtime? What is the configuration of these things? And that still is hard. Nothing is changing. And then the third one here is the allocation which roughly says this software is going to run on this computer and this software is going to run on this computer and there's a terabyte link between these two things and, you know, that deployment. Excuse me? Yeah, exactly. Deployment is another word for security allocation. Allocation can be architectural styles. That is a don't be able to push a ball of dung. The big ball of mud is argued to be the most common architectural style. If you guys ever come to some project and they have no internal divisions and the whole thing is just a big sea of objects, you know, you pick on one thing and you're going, if you keep pulling everything comes out. Wait, are there some other time? I was going to say, you can do it another way. The interesting thing, again, getting back to allocation and deployment, as soon as you put on two different pieces of hardware, you sort of are forced into divisions, right, because one has to be the client and one has to be the server. So, well, they have to be, because they're not all the same memory space. Or pipe it and build their systems or map it and use their N tier and there's, I don't know, half dozen or a dozen of these standards are architecture styles. Okay, so the question in which you can read at the top is, what architecture intent do I encode? And this is the crux of the presentation because this is the only part that's not obvious because everything, once we get past this part, you guys aren't going to remember the exact patterns I'll give you after this, but you're going to be able to re-derive them, like on a physics test, when you forgot about that one thing, but you can figure it out from F equals MA and something else. So my question is, what architecture intent do you think we should encode? Okay, excellent, that's what I wanted to hear. Because if you knew the answer, then I'm really not helping out. So my answer's going to be, we're going to encode a bunch of the intent we just talked about in terms of how do I map between the module view type and the runtime view type? If I have this concept that there is this chunk of code which I'm going to call either a module or a component, can I see those divisions when I look at the code? If I have constraints or properties, like this is an asynchronous call, can I see that when I get to the code? These are the kind of things we're going to take a look at. Okay, so we've got finally to the last section and I got about 14 minutes. Okay, so here's the motivation. When you're reading code, you want to know who talks to who, the variants and constraints that you have to deal with. If I have constraints, I don't mean like, we've only got $50. I mean like, it must be under Java or you know, don't do this following thing. Messages that are sent, received, policy patterns that are abused, performance requirements or guarantees that you have to make, data structures used for communication. By the way, all these are generally fairly easy to see in an architecture model, right? If I go over here to the board for a pair of programming, you say, hey, let's go over to the whiteboard and talk about this for a second and I draw the client and I draw the server and I draw a line between them, right? It's hard to your code to see those three things. Strange enough, right? It can be unless you go out of your way to make it clear. So these are the kinds of things we'd like to see. So, well, I am calling, I stole this language from David Garland, my advisor, an architecturally evident coding style. Imagine you could write two different programs, A and B, and there are functionally equivalent, sort of like that obfuscated code in the view of the code, okay? We're going to call one the normal approach and then what we're going to talk about here is the architecturally evident style, so that when you read that program, the architecture is more evident, as evident as we can be, as we would like to make it, to the first ingredient. Again, we don't care what the computer thinks, we care about the humans thing. So we're going to provide hints to the humans. We're doing that right now, like total expenses instead of just T, and we're using intention-revealing method names, like Kent Vex, who doesn't. But we're also going to do something else. We're going to express architecture ideas. We're going to provide hints. We're going to do more than is necessary for the program to compile. I'm going to say that again. We're going to do more than is necessary for the program to compile, okay? That's what, I mean, T works just as well as total expenses, but we're going to go beyond that here. And the benefits here, hopefully, this is just an assertion, just like the domain and code part is an assertion. We hope to avoid future code evolution problems, improve developer efficiency, reduce amount of time spent inferring the code. We'll hopefully have a lower documentation burden if you guys are even documenting, but it'll be even that much easier. And hopefully new developers will be able to ramp up even faster. And the idea here in this, the last part says that you should be able to infer these things now that you know what I'm talking about. Okay. So one last piece of background information is that there's, we're going to use two different kinds of mechanisms to express this on intent, which I'm calling hard and soft mechanisms. Soft mechanisms are one, they're like method names where the computer can care about this. Whereas hard mechanisms are machine checkable. Who's using EJBs, at least in the EJB3 concept? Okay. So you know EJB2 used to just have a type system where you'd say, I need to implement this interface and you'd implement your remote interface or whatever for EJBs. In the new one, you put annotations in the code, right? Now what checks the annotations? There's some sort of compiler that runs through, checks the annotations and then binds everything up for you, right? So there's a hard mechanism to cause that stuff to work for you. So other examples of hard mechanisms are things like pre and post conditions, if you have something that checks them. Assertions, the language type system that doesn't let you put strings inside of integers and stuff like that. It lets you program in the language, it lets you do that. Design patterns like facade work like this and so forth. Pre-compilers and so forth. Those are all hard methods. So here's the example I'm going to use for the patterns, for describing the patterns. Imagine a friend of mine actually built one of these, an email answering system. The idea is you stick it in an email and what you want to put out at the end is either I figured out how I can answer this email or I give up and you've got to have a human read this thing. I couldn't figure it out. But the idea is if you have a company that processes a lot of monotonous emails like where is my stupid package? And if you happen to notice a package number in there and a stupid package, that's key words. Going through this network, hopefully you could automatically send them back a response that says we believe your package is in Sacramento and if you want more information write us again. So the idea of this diagram, well here's a question for you guys. This picture, is this a picture of the code you think? This is a picture of the runtime structure. It's a little unfair because you didn't draw a picture of it. Make a guess. Runtime structure. Exactly. Why do you think it's runtime structure? Because I don't see anything that corresponds to the value actually. I agree with both of you. Whoever said flow and the runtime structure. Exactly. Because you have bindings and good key. So here, let me just walk you guys through this. Input cleanup would be saying here comes a message I need to share out any HTML tags or email headers or whatever I need. Tagging is where you go through and say I think that's a noun, that's a verb and that looks like a product number. Multiplexer just makes copies of the message and then you run it through a whole bunch of feature extractors and parallel. This thing was, I'm not a linguist, a friend of mine who's a linguist told me this is how you would do it. So, you redefine that into one message and then based upon some technology, could be a neural net or something else, you classify whether or not you can answer this message as this is a request or package status and then you can answer it. Okay, this makes sense pretty much. Okay, so, here's the first pattern. We would like to express module dependencies and when I mean module, I'm talking about a chunk of code. When I say component, I'm talking about something that exists before the time. Okay, that's just the way architecture got stuck with it. So, modules of course depend on other modules and we try and control the dependencies between these things. We try to prevent cycles and so forth but we may have no upward dependencies as a restriction and Java 7 is going to have more support by the way if it ever comes out. Here's the first idea of a pattern is we want to use a tool to just express the dependencies. Okay, there are some open source things like verify design, there's some academic work like module systems for Java. Another option is to use a framework. Okay, if you guys ever used OSGI or dot net bundles or anything like an assembly, sorry. Yeah, now you notice in these things these are systems that allow you to say this depends on this and this can be we combined with this or this can't be. So, essentially those things add to the semantics of language you're working in. Okay, so that's one pattern is to use some external tool or external language to express the dependencies. You could also put comments in the code. Now, why is that not very satisfactory? Yeah, I think pretty quickly. Yeah, get out of sync really quickly. You can't check it on a tool across the check to make sure that, you know, it's hard to express the negative stuff like whatever you don't depend on this, that kind of stuff. You can't force it to read it. Yeah, that's enough. Yeah, we get so dependent these days on the alt space or whatever the command completion is in your IDE because you're just like you start using stuff and if it's marked as private it won't show up for you to call and then you know you're like, I didn't know I wasn't allowed to call that. Second one, oh sorry, this one is just related on package structure. I remember that email processing system, I organized my packages this way. Here's my email answering system with an infrastructure package and inside there's a package filter style, there's a package with system with head and has components and interchanges there. My first question is what can you learn from this package structure? Yeah, you can find for a pretty good class based on a package within what it's intent or what it's supposed to do. Okay, anything else? Students in our modules Sorry, do I have any good modules separating packages? Yes, absolutely. There's a lot of things you could learn from this, okay. Now, can you imagine a different packaging style? Is that how you guys package your stuff? It's not the only good one but it's one that expresses certain kinds of things. In this case it would be easy to find where the components are, right? It would be easy to find where the data structures are to go between the components and presumably this is where the style is. Okay. And so, again, the compiler doesn't care how you organize your packages but you do. So, think about that. So, the next pattern here is the module component alignment. I have source code. I group that into things I'm going to call modules. Those are going to get instantiated at run time. Not everything gets instantiated. When's the last time you instantiated a map library? You don't. It doesn't have any run time structure but you might instantiate a map library. So, what we do is make the components visible in code. We don't have to make the components of modules line up but it's a lot easier to do. Here's one pattern is to align the module component boundaries. You can say things like modules A, B, and C become component-wide. Put concrete games on that. Let's say that the GUI toolkit and the field checking logic and the something or other makes the client. Okay. Another way you can do that is to align a module and what gets instantiated in the component. That's generally very hard to do. Just imagine if you share one module and two different components then you break the one to one. Another pattern here is using a module for different interchange types. You can find out exactly what the vocabulary is of stuff between two different modules or two different components. Okay. I told you this is going to be a module or runtime mapping. The desire here is to make your runtime structures evident in the source code. Now, it's easy to read code and sort of see an algorithm because it's all sort of in front of you. Okay. You can see 100 lines or 20 lines or some other code on the screen. But it's hard to infer what runtime structures are going to pop out. For example, what components are instantiated or what the topology of these things is going to be. So if you look at some code you can see that many clients are going to appear at runtime. Okay. Unless you read the code in a certain way. Here's one pattern. Centralize the architecture instantiation. This works great when your architecture doesn't change at runtime. You guys have architectures that are static or dynamic. Who's got dynamic architectures? Like at runtime could it be like two clients one minute and seven clients the next minute and, you know, no clients. Well, then that's dynamic architecture and it's not a word. Everything is there. Right. And it just runs until you turn it on. Okay. You could do things like co-locate things in the code. Step one is creating instances. We're going to see an example of this in a minute. Second is do you detach all the instances and the third is to start. Okay. The alternative to this is that when somebody reads your code they have to search around to find where everything is instantiated and you've got a GUI and you've got a back end. Sometimes the GUI can talk to the back end from any part of the code. Right. And so you've got just like all kinds of widgets talking back into back end. Another pattern you see is to hoist the initialization and configuration. So if you ever use struts or EJB or OSGI you notice you have to have a configuration file on the side that says A talks to B. Okay. So you have to have a configuration file on the side of the code and you have to have a configuration file on the side of the code. Okay. So here's an example of that kind of code. So for my application here doing email processing I might have a main routine to create the pipes filters and then create the pipes and filters and then start the filters and then create a configuration to simply throw out the code. The computer wouldn't care less because the computer doesn't care where I put this stuff but the person who's reading it might be in good shape. Okay. So here's the next desire is to make components visible in the code. We can use a naming invention. So you could prefix or post fix the name with component like tagging component to represent the component for tagging components. In other words what is that pattern called where you use an interface to mark something like serializable that a partner yeah, we can do the same sort of thing. We can just mark them all with component or we can actually have an abstract superclass called component and that works pretty well. Another pattern here is you can have fields to be run there. So here's an example of that. So we can make an abstract public class filter expense component and it's got some template pattern here that allows it to run and the nice thing is that it standardizes the startup code with the run and work template pattern and if you're in your IDE you can press your magic key like F4 or whatever and show all the subclasses and remember what you're trying to do is communicate to the other programmers you're not trying to communicate to the code or to the machine. Okay, next pattern here is we want to make the components visible in the code and so that should say connectors not components sorry about that so we've got all different kinds of connectors method calls, event dispatches, share variables, whatever but what we want to be able to differentiate right now when you call a method it just looks like every other method right, A calls B okay but what we want to be able to see is oh, here's this chunk of code I call the client here's this chunk of code I call the server and they have a different kind of communication that's going to go over some distinguished channel whether it's a remote method call or a socket call or whatever and we can use a naming convention here to make the connectors visible and one opportunity here is we can move responsibilities into the connectors to make them smart so they can actually do some error checkings or check the protocols and so forth here's an example of this in the code so what we did here was we created a class for pipe parameterized by T that extends connector and we implemented using the job of useful components queues and the idea is then you can read and write to these pipes so we can send email messages especially the JDC connector well the JDC connector is an example of a kind of connector that they do a special connector from your code to a database and so they have different types of connectors depending on which type of database you're talking to but they have the same API on the connector now notice that this is different from the last code you saw the last code you saw this one this one said this is an abstract public class no where do you create your own filters and put all your data in them and it says there's only going to be one implementation of Python and this is it and it hoists all the concurrency nastiness so that nobody else has to deal with concurrency again okay I'm so sorry about the time pattern is to make port types explicit in the code so in architecture we talk about two different things we talk about interfaces and we talk about ports interfaces are generally well there's the quote interface right in concrete terms we talk about interfaces in the code like a Java interface right which is a list of method calls essentially that we're exposing now ports are something different they are something that's available at runtime so for example if you have an Apache server and let's say it's got connections to three different clients right now the clients are all using the same interface right that the API actually in each one of the clients may be different okay so the idea is to use three different ports that would port is not connected with the OS ideal right like port 80 for the web server this is just saying you want to track the connection you have with each one of these guys any sense of an interface it's very similar you can chat offline I'm sorry the problem is I'm trying to shovel this background knowledge on architecture right so I think you're on the right idea here so the first thing we can do is we can reify the port and the second pattern here is we can actually put the protocol tracking inside the port and so then we can check for errors and so forth okay another thing we might want to do is make property styles and patterns visible in the code again we can do this with a naming pattern so we can do things like asynchronous write the names so you can put an app synchronous or an app read-only on these things and the good news is this probably enables better machine checkability with the first one with the soft mechanism this one's a hard and the last one is that you can express styles and patterns with names now you guys already do this with design pattern stuff right you go dot it out visitor right so now you know it's a visitor pattern and you can do the same thing with the type of filter pattern here okay making invariance visible in the code is top again because they're intentional that is for all elements you don't do this thing so the first thing you could do here is you could bake the invariance into the API if you guys ever use a hash table you'll notice you can't add a key without a value right so what they're saying is it doesn't make any sense to do the addition of just a key or just a value so when they do something like this right because this will allow you to break the invariance so the good news is that it's enforced the bad news is it's invisible and as you guys involve the developers may accidentally break the invariance okay now I'm not talking about like you maintain your own code but you're doing the alt space and you start you know coding something up and you don't know that you broke the invariance okay the next one is you express the invariance in the classes you can do things like comments there are modeling languages the next one is you mentioned before is these tasks that are outside the code okay again the test tends to be specific rather than for all tests but it's certainly a lot better than nothing okay anti-powder very treasure now if I use a naming convention like launch space shuttle for a method you get a pretty good idea with responsibility that method is right now what if this thing actually calculates my bank balance and I call it launch space shuttle something but it's really going to do something else don't surprise me I'm two minutes over so I'm going to go real fast all this stuff is dependent on what your code frameworks are if you're using OSGI or what not then you use different things and here we are basically developers know no more about the problem debate and architecture than strictly necessary for the program to work design intent is lost between the design and the code and the principle says that we can express our domain in the code but the idea here in this talk is expressing the architecture knowledge in the code specifically the mapping between the module view type and the run time view type because humans are generally bad at that benefits here is a tremendous loss of part one architecture knowledge architecture is compatible with agile and a couple of resources here there's book chapters on my website and there's an architecture news site I'm trying to get going like slash dots I apologize for the time thank you very much