Fluent interfaces are more than just a pretty way to write code. They can prevent errors, by ensuring your shared code is used correctly.

Our guest Scott Lilly will walk you through the topic of fluent interfaces and demonstrate how it can save you from needing to create the documentation that we never have time to write anyway.

Watch the webinar and learn:

  • What type of code can be improved with fluent interfaces
  • How to design the "grammar" for a fluent interface
  • How to quickly and easily write the code for your own fluent interfaces

Mistake-Proof Your Code with Fluent Interfaces on Vimeo.

Download code samples.

Video Content

  1.  What is a Fluent Interface? (1:40)
  2.  When to Create a Fluent Interface? (4:36)
  3.  How to Build a (Fluent Interface)? (9:58)
  4.  Define the Vocabulary (Functions) (10:14)
  5.  Map the Grammar (15:50)
  6.  Summary (43:42)
  7.  Q&A (44:28)

Webinar Transcript

Introduction

Alex:

Hello everyone, and welcome to today's webinar, Mistake-Proof Your Code with Fluent Interfaces. My name is Alex and I'll be your moderator. I work as a software developer here at PostSharp, and I'm excited to be hosting this session today. I'm pleased to introduce today's speaker, Scott Lilly. Scott is a C# developer and leading practitioner, and today he is going to walk you through the topic of fluent interfaces. Before I hand the mic over to Scott I have a few housekeeping items to cover about this presentation. First, this webinar is brought to you by PostSharp, and PostSharp is a compile extension that adds support for patterns to C# and VB.

So if you are tired of repeating yourself in your code, you may want to check it out, as did folks at Microsoft, Intel, or Bank of America who have being using PostSharp in their projects to save development and maintenance time. By using our products, customers typically cut down their code base by 15%. So feel free to go to our website, www.postsharp.net, for more details, or to get a free trial. Next, today's webinar is being recorded and it will be available after the live session.

You will receive the email with a recording link after the session. So the last thing is we'd love to hear from you during today's presentation. If you have any questions for our speaker, please feel free to send in through the question window at the bottom of the player. We'll be answering questions at the end of the session, and if we don't get to your question during the webinar, we'll be sure to follow up afterwards via email. So without any further ado, I'd like to kick things off by welcoming Scott Lilly. Scott, it's over to you now.

What is a Fluent Interface?

Scott:

Okay, thank you Alex. Today we're going to talk about fluent interfaces, and especially how you can use them to increase your code quality. Here's an example of a fluent interface for sending an email. If you're not familiar with them, it's just a way to write your code so that it almost looks like a natural language sentence. You've got fluent email, dot create email using SMTP server from/to.

You could show this code to a business analyst or a software development manager, and they'd understand what the code is supposed to do. This is also good for any library code that you're going to write. I do mostly large projects for corporate clients, and those often take years of development, and have dozens of team members, some who leave during the project and some who come back, some new programmers. We don't want to spend a lot of time explaining our framework code, our libraries that we use.

And fluent interface can actually help them use our libraries much easier. It kind of instructs them as they go along. You can only call a function in a particular order, and it uses all the functions and sets all the parameters that our classes need. Now, I've got a quick question here. You don't need to answer it, you don't need to type in an answer, but how many attempts does it take to plug in a USB device? For those of us who work in technology, we've done this hundreds of times, and we know that the answer is three. Because you try to fit it in, you have to turn it upside down, still doesn't fit, turn it back upside down, and now it actually fits in.

Why is that? Because the USB ports were not designed to be mistake proof, and we don't want to do that with our code. We want to write code that is kind of like a power cord: It can only go in one way, it can only be used the correct way, so that way anyone who uses our code isn't going to have problems. So what we're going to cover in this webinar, first I'm going to talk a little bit about when you might want to use a fluent interface, so when you see this come up you can say, "Ah, I should think about adding a fluent interface here." And then we'll talk about how to create one, we'll define the vocabulary in our fluent interface, which would be the from, the to, the BCC, and all that.

And then we'll define the grammar, the way we can make it so that anyone who uses our classes with the fluent interface has to use it correctly. And then we'll actually write some code to see how you might do this with a sample report generator class. 

When to Create a Fluent Interface

1. You want to prevent running potentially-dangerous code

First, you might consider creating a fluent interface when you have potentially dangerous code that could be run, and you want to make sure that the developer that calls it can't do something incorrectly. For example, here's a function to delete accounts that haven't logged in for over one year. We've got a SQL connections, we create a SQL command, we've got our SQL command text, and we say, "Execute the non-query," except there's a problem here: This SQL statement doesn't have a where clause on it.

Now, I know no one here has ever done this, especially I've never done this, running a delete statement without a where clause, but you probably know someone else who has done this. And it would be nice if we could find a way to prevent them from ever doing a delete all, delete* from the table unless they actually wanted to do that. So what we can do with the fluent interface is we can build a DB cleaner class. After they set up their connection string information and they tell us the table they want to delete rows from, the only two options they have are to either call a delete with some sort of condition, or specifically call a truncate table. This is one way we can make our code mistake proof. No one could accidentally delete everything. 

2. Code must be called in a specific order (hidden requirements)

Another situation where we might want to create a fluent interface is when code has to be called in a specific order, kind of some hidden requirements. I know this is a violation of object-oriented programming principles, but here's an example of Microsoft doing something in the .NET framework that violates those principles. If we want to send an email, we have to create a new email message, and then we have to set these properties. We don't have any requirements for setting these properties, so we could forget to include the from, forget to include the to, and then when we get to the SMTP client, to actually sending out the email, what's going to happen?

Is it going to throw us a nice, clean error, or is it going to silently fail? Same kind of thing could happen with the code that we write. We create an instance of our object, you have to set a bunch of properties, or call a bunch of functions in a specific order, and then you can call the final function that does what you want it to do. With a fluent interface, we can build something like this so that you have to go in a specific order, you have to include certain things, even though this one has some optional parameters like CC and BCC. And you can't call descend until you've done all the required things, until you've set all the required parameters.

So this is another way we can keep our code mistake proof with a fluent interface. 

3. A function has many overloads, almost-overloads or optional parameters 

Of course, one way that we try to get around problems like this is we create a big function that has 20 parameters, and we end up with a third situation: You've got a function in a class that has 15, 20, 25 parameters, and then you have a bunch of overloads on it, and you have optional parameters, and you have some functions that are almost overloads but not quite, because they don't meet a couple of parameters, or this one needs an additional parameter, and your code just gets very messy that way. So I'm going to show some code here, this is going to be what we're going to work with, and this is a sample report generator that fits the third situation.

We have a create sales report, and we have to pass in this long list of parameters which I've actually seen some of these that are even longer, like I say, 20 or 25 parameters. And then, over time, we usually end up building other versions of this create sales report. So we have one here, create sales report for all categories, which has pretty much the same parameters, except it's missing the category parameter, because we want to include everything. Then, our manager says or the user asks us to add something that lets them create the sales report for all salespeople. So we have a function here that eliminates the salesperson ID parameter. And then eventually we'll have one that says, "Create sales report for all categories and all salespeople," that gets rid of the category ID parameter and the salesperson ID parameter. And we could end up with ...

I've seen some classes like this that get up to 30 or 40 functions that are basically the same thing. This is often happening in report generating classes, export classes, anything that gets kind of dynamic.

How to Build a Fluent Interface

Define the Vocabulary (Functions)

So what we're going to do is build a fluent interface for this fictitious sales report generating class. 

First thing we'll do is we need to know what type of functions we're going to have in our fluent interface. I break this down into ... I use the acronym ICE, I-C-E. We have some instantiating functions. These are the ones that actually create the report generator object. We have our chaining functions. These are the ones that let us add parameters to the object. And then we have our ending function, or our executing functions. This is the one that actually does something.

So if we look at the report generator class for our instantiating function, we're going to call it once at the start, and it has an action name, usually. I'm going to call this one "create sales report". And we can make it whatever we want. Then, we are going to determine what chaining functions we need. And this is where we're going to replace passing in a long list of parameters, or setting properties like we did in the email class. And for our sales report, we're going to have our parameters like from, to. If we look at the code, we've got our start date, our end date, our list of category IDs to include, our list of salesperson IDs to include, how we want to group it, how we want to sort it, so on.

And then we finally get to the ending function, and this is the one that's going to build the report. So all of our other functions before, we're going to say, "Start building the report with our create sales report," we're going to pass in all of our parameters, and once we get to the point where all of our parameters are set, we can say, "Build the report." So when we get the chaining functions, we're going to look here, since this is an existing class, at our parameter list. That's what we're going to use to actually find our vocabulary. So we're going to want to be able to pass in a parameter for the starting date, the ending date, the categories. Since we have different versions down here, we want some way of saying, "Create the sales report for all categories."

So we want to either be able to say, "Create it for all categories," or, "Pass in some category IDs." Same type of thing for the salesperson: We're going to want to have some way of telling our fluent interface, once we get to build reports, we should create it for all salespeople, or optionally, we can have a list of salesperson IDs that have been passed in. As we look at all the parameters, this is what I ended up building for my list of the vocabulary. For the instantiating, I'm just going to have the one function, create sales report. We could expand this and have other instantiating functions: Maybe you wanted to have create current month's sales report. And that way, it eliminates you needing to pass in the from date and the to date.

Or, you could have create end-of-year report, or create unchipped order report, and that would automatically set some of these other parameters for us. For our chaining functions, looking at the different parameters we had and different scenarios we had for our report, I want to pass in a from date, a to date. I want to be able to set it so I can include all salespeople, or so I can include specific salesperson IDs. And I put a little asterisk here to remind me that this one, I want them to be able to call multiple times. Same thing with include categories. And then down here at the include returned orders or exclude returned orders, I could've made that so it was just a boolean parameter that we pass in. It could be include returned orders and then pass in a parameter, but I like to have it a little bit more ...

The whole idea of the fluent interface is that it kind of sounds like a natural sentence. So I like to have different ones that include or exclude for the boolean properties, instead of passing in a parameter. It just makes the sentence read a little bit more naturally to me. And then at the end we'll have the build report function. This is going to return an object in our code here, but this could, in a real situation it would return maybe a PDF file or some other report-type object. You could even have multiple ending functions, you know, build PDF report, build SSRS report if you're using SQL server reporting services. Whatever you want, but just for this demo we're going to keep it kind of simple. So now that we have all the functions that we want to include in our fluent interface, this is kind of the vocabulary, the words we're going to use.

Map the Grammar

Now, we need to set up the grammar, which is the rules of what function can be called after which function. And this is how we're going to mistake-proof the code. We're going to have rules that you can't get to the build report until you've passed in all the required parameters. The way I do that is with a spreadsheet. You could do this with paper if you want. I just did it with a spreadsheet so it looks a little bit nicer. In the rows, you're going to include your instantiating functions and then all of your chaining functions. You don't need to include your ending functions, so here you've got create sales report as our instantiating, and then all of our chaining functions. For the columns, this includes all of the chaining functions and then all of the ending functions, the build report.

So we don't have create sales report in there, we just have the chaining and the ending. What we're going to do now is actually map out what can be called after each function, and I'll do that with the actual spreadsheet. So here, after create sales report, I'll just pull up a little screenshot there, after create sales report, the next thing I want to be called is from, and that's the only thing I want the developer to be able to call. So I just put a little yes in here to mark that after create sales report you can call from, and you can't call any of the other things. After from, the only thing I want the developer to be able to call is to. So I look in the from row, find the to column, and set that TS.

After to, I want them to be able to call include all salespeople or they could call include salesperson ID. So I go to the to row, look for the include all salespeople, set that to yes, and include salesperson ID, set that to yes. Now, for include all salespeople, the next thing I want them to be able to call is include all categories or include category ID. Because if they select include all salespeople, we don't want them to be able to include individual salesperson IDs. That's kind of useless at this point. So for include all salespeople, the functions we're going to allow next are going to be include all categories and include category ID. So I can go in there, in the spreadsheet, and mark those as yes. Now, include salesperson ID is a little different.

I want them to be able to call include salesperson ID a second time or a third time. Or, once they've added the last one, they can call include all categories or start including category IDs. So the spreadsheet for that is going to be yes for include all salespeople, because that's an option, yes for include all categories, and yes for include category IDs. And then I'd work this way for the rest of the functions, for the rest of the instantiating and training functions. And eventually, I would get a list that looks like this. So now I know the only time build report can be called is after this last include unshipped orders or exclude unshipped orders is called.

Because at that point I know we've gotten through every other required parameter correctly, and now we can do the ending function. So the next step ... I'll delete this one. So the next thing we need to do after defining the grammar is we need to give some names to some interfaces that we're going to create. This is how we're going to enforce the grammar, by having interfaces returned from our functions. And I like to make them nice and simple for the create sales report. The only thing you can do is set the from date, so I've named it "I can set from date". After calling from, the only thing you can do is call to, so I named that one "I can set to date". After you call to, you've got a couple of options.

So I named this interface "I can set all or one salesperson". And if you go down, let's see, here to include returned orders and exclude returned orders, they both can do the same thing. They both can call include unshipped orders or exclude unshipped orders, so they have the same name. Because what we're doing to do with this interface is say, "These are the functions you can call next." Since they have the functions they can call next, we're going to use the same interface, and this is how we build the grammar. 

Write the Code

So now, let's go into actually building a code. I'll start with a report generator class, and this is similar to the other one with some enums that I have for sorting and grouping, and I have no functions in this yet.

What we need to do is create a private constructor, because we don't want anything to be able to construct a report generator object other than our instantiating functions. That's the only way we're going to allow those to be instantiated. And then I'm going to create my first instantiating function, the create sales report, and for right now, I'm going to have it return the report generator object. This will be public static, because it's going to be like a ... It's a factory method, basically, the factory design pattern. And for right now, we're going to have it return a report generator, and that's all it's going to do. So when we call ReportGenerator.CreateSalesReport, it will instantiate our report generator and pass it back.

Then, I'm going to set up some ... Right now I'm just going to set up the from, the to chaining functions, and these will be public, and I'm going to have them return report generator, and this will accept the date/time parameter, and it's going to return this. So this is how we do the actual chaining. Each one of our chaining functions is going to get the value, and the final thing it's going to do is return the object that was called. So this is standard method chaining. If you've ever done anything like with a string object, where you do string.true.toupper.substring or something like that, that's method chaining, because the string.true returns a string so you can do another function that you can do on strings, like toupper. Toupper returns a string, so you can do another string function.

You can call another string function from that, like substring. And that's the method chaining that we're going to use. But for the fluent interface, the whole idea of the chaining function is to get parameters. So I'm going to need to create a private variable to hold the parameter value before we return the object. Then I'll create the to function, which will also return the report generator object, and we're going to need another private variable to hold our to parameter. And this will return this at the end, so we can continue the chain. Then eventually, we're going to get to our ending function.

I'm going to skip the other chaining functions for right now just so I can show how the method chaining works. And the ending function here is actually going to return an object. In reality, since it's the build report, it would probably return some sort of report object, but we're just going to do this for right now. But the build report function would then look at all the different parameters we've set, do whatever it needs to do, and then return the object. For the email fluent interface, that would actually be more of a ... When we had the send email, that would actually be a public void function, because that type of function is just going to do something. It's going to send the email and it's not going to return anything. The same type of thing with the delete.

If we were to build a fluent interface and the final thing was delete some rows from a table, that's probably going to be an execute non-query which we don't care about any return results, so it would be public void. But for this report generator one, we're going to assume that the final call, this build report, is actually going to return something. So now, we can look at some calling codes for this to see how the method chaining works, save our report equals report generator dot, and then IntelliSense shows me create sales report is the only function available, because it's a public static one. So I call that ... Now, if I press the period again, IntelliSense shows me the functions that I created, the public functions. I've got build report, I've got from, and I've got to. So I could call to, date/time, UTC now, from, date/time, UTC now... Add months, minus one, and then I can call the final build report.

 

So this is how the method chaining works, because create sales report returns a report generator, and the report generator has to, from, and build report as possible functions. But you might notice I did those out of order. My chaining, I want it to do from and to. That's kind of more of a natural sentence, but this still let me do it. That's because we haven't installed any of the grammar yet, we haven't set up the grammar with the interfaces. And this also still has the possibility of us forgetting to include from. Will the report still work? It depends on how well we wrote our build report function, but we're going to add the fluent interface to make sure that we call all of the correct chaining functions first.

Alex:

So Scott, just looking at this example, I'm wondering if there's possibly any tool that can generate some of this API code for us, like some initial code. It seems like it could be possible, just based on the grammar that you defined.

Scott:

That’s a good question, Alex. I started looking for something a few months ago and I didn't find anything, so I started a little project, an open-source project I'm going to build. But everything else has gotten higher priority. I'm hoping to get back to it soon.

Alex:

Well, that would be very nice, I think, to have something like that. Okay, well, looking forward.

Scott:

Okay, and at the end of the webinar, I'm going to have the link to a page on my site for all the source code. And if I have, or when I have that finished, I'll also include a link to that project. It's going to be up on GitHub.

Alex: Great, thanks.

Scott:

You're welcome. So another thing we can do, just a quick little thing to mention, is within our chaining functions, mostly all they're doing is setting parameter values and returning this. But we could add some additional validation rules in here. So we could say something like, "If to is less than from, throw new arguments exception," or something like this. Just another nice way to make our class a little bit more helpful to any other developers that might be using this.

But for right now, I'm just going to take these out. Now, I'm going to paste in all of the functions because I'm sure you don't want to watch me mistype commands on Visual Studio. So now I've got all the chaining functions in here, our from, our to, our include all salespeople, which is setting a boolean, our include salesperson ID, which adds the ID to a list, our group by, sort by, and so on.

So down here in the build report, we would look at all of those values that were set in these private variables, and use those to actually build the data set for our report. So the next step is we're going to create the interfaces. You could do this a little bit differently once you get some experience with it, but I kind of want to show step by step how this flows, how you could develop it. So what I need to do is I look at all of the interfaces here, and I'm going to just get a unique list of these, and I'm going to create those in the source code. For this sample, I'm going to create them inside the reportgenerator.cs file. You could put them in external files.

Normally, I don't like to put more than one class or more than one interface in a file. But these interfaces are only ever used by the reportgenerator class, so I'm not going to worry too much about that here. Then I'm just going to create public interfaces, I can set from date. And then set one for ... I can set to date, and again, I'm going to paste these in so you don't watch me type. But we're going to have one empty interface for all these different classes, or for all these different interfaces we've defined here in the spreadsheet. So now, these are all available as places for us to put our grammar in. Next thing we need to do is have this report generator class implement these interfaces, and I'm just going to paste in the names of all those interfaces up here.

Alex:

Okay, I've got another question: Maybe you can suggest any tools or practices, how to write this code faster. Maybe once you've finished the initial example, or just in general, some suggestions. Because it seems, while we still don't have this automated tool, it can be quite laborious to follow all this manually.

Scott:

Yes, the first time, if you set this up manually, it does take a bit of work. The idea is it's kind of an investment so that down the road everyone can use your library codes. But one thing you could do is instead of creating these functions, you could create the interfaces that are populated correctly, and I'll show you how we actually do that next. And then, have your report generator class implement these interfaces, and use a refactoring tool, like ReSharper, and say, "Implement the interfaces."

Alex:

Yeah, so it can generate at least a bit of that for you.

Scott:

Right, that would go and create all of these functions for you. You'd still have to go in, and have it return this, and set the private variables, but at least that way you're structurally building a lot of the code automatically.

Alex:

Okay, thanks.

Scott:

You're welcome. Okay, so now the next step is to actually have the functions return the correct interfaces. Because right now, they're returning report generator, which exposes every function in report generator. If we go back here to the calling code, and after I call to, IntelliSense shows me all the functions, and I can even call to a second time. So we want to use the interface to actually control what function can be called next.

And the way we do that is by going back to the spreadsheet, and seeing that create sales report, the interface that we want it to return is I can set from date. So I'll just copy that, go back in my code, and change its return type from report generator to I can set from date. It's still returning a report generator object, but it's casting it as an I can set from date, so the only thing that would be visible is any functions we've defined in the I can set from date, and this is how we're going to set up the grammar.

And I would go and do this for all the functions, change its return type from report generator, the temporary one we're using, to its actual correct one. And again, so you don't have to watch me type, I'm just going to copy and paste all that in. So now, each one of these functions, like conclude salesperson ID, it's going to return the object, but it's going to return it as an I can add salesperson ID or set categories, which is how we have include salesperson ID defined here in the spreadsheet.

So then, the final step is to actually add the functions that you can call next inside the different interfaces. So for example, I can set from date, if we look at the spreadsheet again, the only thing you can call is from. So I'll go up here in the code, find the from signature, I'm just going to copy that, and put it down here in the interface. So if we go back to our calling code, after I call create sales report, if I hit the dot, IntelliSense shows me the only function available now is from, so this is how we enforce the grammar. And if I do dot again, the only functions that are available are the ones that are available in object, because we haven't set up the rest of the interfaces.

So what I do next is for, I can set to date, we need to have it called the to function. So I'm going to add that to this interface. Just copy the signature of it, add it to the interface, and now if we go back to the calling code, and I type dot, IntelliSense shows me that to is available. So I'm going to just copy in all those, because we all know the worst way to mistype something is when you have hundreds of people watching you. And now, the interfaces are all defined. So now, we know the flow of what functions can be called after which function. And if we go back to the calling class, now we see to is available.

If I hit the dot again, IntelliSense shows me that my next available options are include all salespeople or include salesperson ID. So I'll use the include salesperson ID. Now, it shows me the only available options are include another salesperson ID, or start moving on to the categories. So I'll include another salesperson, then I'll say, "Include all categories." GroupBy, then I've got the SortBy next, and I'm going to say, "Include returned orders and include unshipped orders." And then finally, since all the parameters have been passed in and set for our class, we can call the BuildReport function, and that's how the fluent interface would work.

Alex:

Okay, I've got one, I suppose last question maybe from me. I was just thinking about LINQ, how it's kind of a fluent API is based on extension methods. So my question is how these extension methods can kind of affect our API that we design, our fluent API. On one side, you can make it extensible, but on another side, there's probably some consequences, and some probably things that we cannot ... Or we need to protect from properly, right, when someone tries to extend interfaces with extension methods that we didn't expect.

Scott:

Oh yes, I know the big problem I have in LINQ is when you have something in the middle of your LINQ chain that unexpectedly returns nul, so if you have a collection and you're doing collection.first, and you put in some sort of condition, and it doesn't have anything that matches that condition, yeah, then it returns-

Alex: Exception

Scott:

Yes, yes, because the rest of your chain, it says, "I've got nothing to work with." But the nice thing with the fluent interface is, since we're writing them and controlling them, everything is always going to return this at the end, so we know we don't have that possible null problem.

Alex:

Okay, yeah, so we need to pay attention to that.

Scott: Yes

Alex: Okay. Thanks.

Summary

So I'm just going to put this little closing slide out here: The next time you have a project where you're writing something that you think, "This is potentially dangerous," or, "Someone could misuse it, or miscall it, or not know how to use this function," especially if it's some framework code, or some library code, or something you're going to share on open source, don't write your code mistake possible, like the USB. Instead, consider putting a fluent interface around it for your facade, to make it easier to use, and also to ensure that other developers can only use it correctly.

 

 

Q&A

Here are Scott's follow-up answers to the questions. If the question was misunderstood, not answered completely, or if you can think of a different answer, please let him know by leaving a comment at http://scottlilly.com/FIWebinar.

Q: So from and to on create report are methods code after create report. If those values were required, can we provide these values as parameters to the create report method? I got the grammar should be present on the method name, but I understand also that the parameters of a function are part of the overall signature.

A: One possible thing we could do, so let's say we wanted to have something like CreateSalesReportForDateRange and include the from and the to in that, so then what we would do, we'd that here to the spreadsheet, I'd look to see what I can call next. So obviously, I don't want them to call from, I don't want them to call to. I want them to go onto the next step, which is basically the same as calling the To. So we would use the same signature as calling the to, and I would create another instantiating function, public static. See ... Get the correct interface, I can set all or one salesperson. Then, take our to parameters, and what we'd have to do is because this is a static function, we're going to need to a little bit of work on this.

But I would say you need to create another private constructor that takes those values, and set the parameters, set our private variables in here, and return new ReportGenerator with from and to, and I think that should work. So if we go back here, off our ReportGenerator I can see ... So I've got two options now: CreateSalesReport or CreateSalesReportForDateRange, and if I call that one for the date range, I can pass in the to date times. And now, when I hit the period, IntelliSense shows me that my next options are not from and to, but they're instead include all salespeople or include salesperson ID. So that would let our code look like this.

Alex:

Okay, thanks. I suppose that would be the answer, that basically, adding parameters to some of these methods is also a valid option. It's just probably, you need to pay attention not to add many parameters, because you go back to the same problem.

Scott:

Right, I generally like to keep one, maybe two parameters, sometimes zero. Like this include salesperson ID, we could also have created one that doesn't just take an integer, but it takes a list of integers. So maybe in the UI, the actual user is checking which salespeople they want to include, and we would pass a list of those IDs to the function. So then, we'd want an overload here, or we'd want another ... Include all these salespeople that accepts a list of integers.

Q: What's the reason to return type of an object instead of report generator and build report?

A: Because the build report is our final function, it's the one that's actually going to do something. So for this example, build report in reality would probably return like a PDF file, or some other type of object. You could also do this, like if you were doing, let's say, an average calculator and you wanted to do ... Your syntax would be like .includevalue.includevalue, and just, you're keeping all these. You keep passing in values, then your final function would be, your ending function would be calculateaverage, and that would return a double or whatever you wanted. So it all really depends on what your actual business purpose of this last function is.

Alex:

Okay, so that was just a sample object, in that case.

Scott: Right. 

Q: How would you have default values and avoid too lengthy code? Let's say for example that 90% of the time you would include all categories so I would not want to repeat that each time I use the FI.

A: You could make an instantiating function named „CreateStandardSalesReport()“ (for example). Inside that function, it would call the private constructor and set the default values. Its returning datatype would be an interface that is farther in the chain, past the functions for variables that were automatically set inside CreateStandardSalesReport.

Here is an example of how that might be done: https://gist.github.com/ScottLilly/85091b9f61e66256a69a7909a05337fd

I would change the interfaces, so the functions that can be skipped over are first in the „chain“. It’s easier to skip over the first five functions (for example), than to create interfaces and functions that let you optionally skip over the first two functions, then the fifth function, then the seventh function.
You might also want to integrate the Builder pattern, as mentioned in one of the questions below.

Q: How does this compare to the "Curiously Recurring Template Pattern" such as expressed here?

A: That pattern is an interesting way to do method chaining. Although, it looks like you will still need to create individual interfaces, to enforce any grammar rules.

Q: Can't you just use annotations to require a certain order and ensure parameters contain data?

A: Yes, you could use annotations on an entity, to ensure the required properties were set, before being able to execute a function. However, another developer could forget to set a property value, and the error will only be detected at runtime.

With the fluent interface pattern, other developers will have the additional help of IntelliSense, to lead them through the chain of required functions to call. They could still pass an invalid parameter to a function. However, they would not be able to skip over calling the function.

Q: Can we use Builder pattern where we create different set of Builder class for different values of Report properties?

A: Yes, you could combine fluent interfaces with the Builder pattern. That would be a good way to handle a situation where you have several common ways to set the values for the some of the chaining functions.

For example, if Accounting reports should always call IncludeAllSalesPeople, IncludeAllCategories, ExcludeReturnedOrders, and IncludeUnshippedOrders, that could have one Builder class that calls those functions. You could have a different Builder class to set the values to only include all the categories for items that are physical products (and not downloadable items), for the Shipping department.

Q: I would like to know about many Id's inside the filter, how to deal with this?

A: If I was building the ReportGenerator class for a real program, I would probably have a function for passing in a list of Salesperson IDs (as if the function was receiving a list of checked items in a datagrid that displayed the salespeople).

Inside that function, I would add the IDs from that passed parameters into the private _includedSalespoersonIDs variable, if that ID was not already in the list.

Q: Is this the only way to implement fluent interfaces? If not, what are the other approaches and how are they different from your approach?

A: This is the only way I’ve used. You might be able do something similar with extension methods that only work for specific datatypes (which would be the interfaces we use for the grammar). But, method seems less clear, to me.
If anyone is aware of a different method, please share it.

Q: How would you implement the IncludeSalespersonID function within the report class or option that are mutually exclusive when the report is actually being built?

A: When you create your fluent interface’s grammar rules, you should design it to prevent mutually-exclusive functions. For example, in the ReportGenerator fluent interface, you can call “IncludeAllSalespeople”, or you can call “IncludeSalespersonID”. You can call “IncludeUnshippedOrders”, or you can call “ExcludeUnshippedOrders”. You can only call one, or the other – not both.

Q: How exception handling works in fluent interface? How it works with optional parameters?

A: Exceptions would be caught at runtime. You could add parameter validation, that could throw an exception if the passed parameter was invalid. Also, when the ending function is called (BuildReport or SendEmail, for example), it could throw an exception.

The fluent interface can ensure that, when other programmers user your class, they will call the all the required functions to set the required parameters. However, if you do not include other data validation, they could set the parameters to invalid values – for example, setting the “to” date before the “from” date, when specifying a data range.

Q: Would it be possible to convert BDD scenarios to fluent?

A: This seems like it could be a great idea. I haven’t used SpecFlow, but a fluent interface would almost match with creating FitNesse fixtures.

This seems like it could be a great idea. I haven’t used SpecFlow, but a fluent interface would almost match with creating FitNesse fixtures.

If you show the users (or business analysts) the concept of method chaining, they should be able to create the grammar for you, using business terms. Then, you could use that to build the required fluent interfaces.

This is definitely an idea I want to think about some more. It may be a great way to deal with correctly understanding complex business requirements.

Q: If include All categories is optional, will the group by sort by be available to continue with the BuildReport? So, the order would include a Build report method for all functions that are deemed optional?

A: If you build the grammar to allow that, it should let you create that as a valid “chain”. I think the answer to the first question (<a href="https://gist.github.com/ScottLilly/85091b9f61e66256a69a7909a05337fd">see source code here</a>) will show how to do that.
Please let me know if that sample doesn’t answer your question.

Q: How to handle exception thrown by preceding method? How to stop chaining, or ignore error if not critical and continue chaining?

A: The chaining functions only set the values of the private variables, and “return this”. So, there should not ever be an exception – unless you add your own data validation in those functions. In that case, when the code is run, and an invalid parameter is passed, it will throw whatever type of exception you specify, and stop executing.

You could put logic into the chaining functions that would check if the passed parameter is invalid. If it is, instead of having the function throw an exception, you could have it determine a good (or default) value to use.

Q: Over time, let's say the ReportGenerator might add new functionality. Is it possible to have more than one path to reach the ending function? And how can we ensure maybe though unit testing that the chain leads to an ending function?

A: Yes, it is very possible to have more than one path reach the ending function. The ReportGenerator class has several possible paths (Include, or Exclude the returned and unshipped orders, for example).

Ensuring complete unit testing of all possible chains is interesting. If I was doing that, I’d probably to TDD, and use ReSharper (or some other static analysis tool) to show any functions in any interfaces that are not called. By looking at uncalled functions in the interfaces, that should inform us of any missing paths.

When I work on the fluent interface creating tool, that sounds like a good feature to add – automated generation of unit tests for each chain.

Q: I think you just need to get the result of IncludeSalespersonId inside the foreach and continue from there to avoid the casting.

A: I think this example is a little tricky, because you must either enter at least on salesperson ID (through IncludeSalespoersonID), or call IncludeAllSalespeople, before you can call one of the category-setting functions.

If you have an example that works, please share it at http://scottlilly.com/FIWebinar

Q: How would you go about baseclassing and extending this pattern with generics and inheritance is the essence of what I am trying to understand?

A: I have not tried to create a generic version of a fluent interface engine. Every time I’ve built a fluent interface, it has been very specific to one class (such as the ReportGenerator class).

If you needed to create “chains” for a class that were extremely different, you might want to have ReportGenerator as a base class, and create child classes, with their own interfaces that implement the different chains. For example, if you wanted to have a ManagementReportGenerator fluent interface for management reports, which might show different information, and have very different “chaining” options. You might also have an AccountingReportGenerator for the accountants, which might have a massively different fluent interface. Those would have their own sets of interfaces, but might use some functions from the BaseReportGenerator class.

Q: I want to call one interface or a different one according to a value previously set. For example, would this be possible? if IncludeSalesPersonID is called then AllCategories is selectable, and if they select allSalesPersons, then AllCategories is not enabled (to prevent a call from being too big).

A: Yes, you could do this. When building the grammar spreadsheet, in the row for IcludeAllSalespeople, don’t put a „Y“ in the IncludeAllCategories. Then, your interface for that row might be named IcanSetOneCategoryID. That interface would be defined to only have one function „IncludeCategoryID“, and its return datatype would be „ICanAddCategoryIDOrSetReturnedOrdersInclusion“.

 

About the speaker, Scott Lilly

Scott Lilly

Scott Lilly is a C# developer, creator of "Learn C# by Building a Simple RPG", and lean practitioner.
Scott develops line-of-business systems for corporate clients, and publishes videos and tutorials for C# developers.
Scott's blog.

 

Design patterns are not just for architects. In fact, you already use Design Patterns but probably don’t know it. Observer, Proxy, Facade - these are patterns that allow us to better communicate our ideas with other developers. And once we understand the patterns, we can use solutions that people way smarter than us have already implemented.

In this session, Jeremy Clark takes a look at several Gang of Four patterns that we regularly use without realizing it. Don’t know who the Gang of Four is? Watch the webinar to find out.

Watch the webinar and learn:

  • What design patterns are (and what they are not)
  • How design patterns offer solutions to common problems
  • How we already use many design patterns, including Observer, Proxy, and Facade
  • How our modern languages support design patterns

Design Patterns: Not Just for Architects on Vimeo.

Download code samples.

Video Content

  1.  What Are Design Patterns? (3:33)
  2.  The Gang Of Four Book (5:29)
  3.  Anatomy of a Design Pattern (7:09)
  4.  The Gang of Four Patterns and Categories (10:31)
  5.  The Book Head First Design Patterns (12:49)
  6.  Why Care about Design Patterns? (15:33)
  7.  Observer Pattern (20:28)
  8.  Proxy Pattern (31:18)
  9.  Facade Pattern (40:39)
  10.  Summary (47:42)
  11.  Q&A (49:39)

Webinar Transcript

Introduction

Alex:

Hello everyone and welcome to today's webinar, Design Patterns Not Just for Architects. My name is Alex and I'll be your moderator. I work as a software developer here at PostSharp. I'm excited to be hosting this session today. I'm pleased to introduce today's speaker, Jeremy Clark. Jeremy is Microsoft MVP for .NET and a Pluralsight author. Today, he's going to show you how modern languages support design patterns.

Before I hand the mic over to Jeremy, I have a few housekeeping items to cover about this presentation. First of all, this webinar is brought to you by PostSharp. PostSharp is an extension that adds support patterns to C# and VB. If you're tired of repeating yourself in your code, you may want to check it out as did folks in Microsoft, Intel, Bank of America who have been using PostSharp who have been using PostSharp in their projects development and maintenance time.

Customers typically cut down their code base by 15% by using our product. So, feel free to visit our website, www.postsharp.net, for more details and to get a free trial. Next, today's webinar is being recorded and the recording will available after the live session. You'll receive an email with the recording link.

The last thing is we'd love to hear from you during today's presentation. So, please if you have a question for our speaker, feel free to send it through question window at the bottom of your player. We'll be answering the questions at the end of the session. If we don't get to your question, we'll be sure to follow up later afterwards. Without any other further ado, I'd like to kick things off by welcoming Jeremy Clark. Jeremy, now it's over to you.

Jeremy:

Thanks, Alex. Today, I am going to talk about design patterns. The reason for this is I always thought that designs patterns were one of those things that were just for architects, but I found out that they're extremely useful to everyday developers as well. My eye opening experience was when I was working at corporate developer, I worked on a really awesome team.

The developer who sat next to me, he had 10 years of experience on me as far as being in the industry. One day he just pops up out of his desk and he's really excited. He says, "I've been using the facade pattern without even realizing it." I thought well, that's kind of cool but it's also a problem because that means that we've been using something accidentally rather than using it intentionally.

What I found is that, in looking at patterns, once I start to recognize the problems that they're trying to solve, now I can associate that with the design pattern, it leads me to a solution that I can look up implementations online and I can create my own implementations if that makes sense. That's really why I started getting into the design patterns world.

Now as Alex mentioned, I am a Pluralsight author and if you do want to dig into the topic a little more, I do have a course on Pluralsight called Design Patterns On-Ramp. It talks about some of the things I'll be talking about today, but it's also about three and a half hours long. So, there's a lot more material than I have time to cover.

If you're not familiar with Pluralsight, really awesome online training. If you learn well by video, I would highly, highly recommend it. I'll have a link to this at the end of the slides as well. But with that said, let's go ahead and get started talking about design patterns themselves.

What Are Design Patterns?

Now, I really hate putting big blocks of text up on the screen, but in this case, this is the definition that has entered our industry as far as what design patterns are. Each pattern describes a problem that occurs over and over again in our environment and as programmers we should recognize that.

There's times where I need to get notified when a state changes. There's times where I have to be able to create three different objects and inject parameters into them. There's times where I might say, you know what, I need to pass the message along between different objects. These are problems that occur over and over in our environment.

Now design patterns, after they describe the problem, they then describe the core of the solution to the problem. So, design patterns aren't actually telling us here is the code you need to write. They're saying here's the ideas behind it and it's actually up to us to implement that idea. In fact, if we continue with this definition, they describe the core of the solution to the problem in such a way that you can use the solution a million times over without ever doing it the same way twice.

Now, obviously that's not something we would normally recommend because we don't want to reinvent the wheel, but there are different kinds of wheels that you can choose from. Now, the really interesting thing about this particular definition that comes from Christopher Alexander is that it has absolutely nothing to do with software. Christopher Alexander was actually talking about architecture, like real architecture with buildings, and bridges and things like that. Now, it turns out that this definition did apply very well to the software environment and so that's why we picked up on it.

The Gang of Four 

Now, there were some, I would say, really smart people who thought about this and they created this book, which you might have heard of. It's that infamous Design Patterns book, Elements of Reusable Object-Oriented Software. If you've ever heard the term Gang of Four, this is what we're talking about. This is the Gang of Four book. Usually we call it that because it was written by four different authors and it's easier to say Gang of Four than try to list out all their names.

The Gang of Four book is one of those books that every developer has to have on their shelf because it makes you look really, really smart. The problem with the book is it's pretty academic and so it's a little bit difficult to read. So, you might say, "I don't know about this. Are design patterns important?" The answer is yes they are, definitely. This particular book described 23 patterns.

The reason why this became so important in our industry is because this was the first design pattern catalog. Now there's way more than 23 patterns now. There's hundreds and probably thousands of them out there, but this was again the starting point. This book was written way, way back in 1994. If you think about that, it's like what is that in computer years? That would be like 300 computer years. So, we start to question, are they still relevant? Again, the answer is yes and we'll see why as we go along today.

Anatomy of a Design Pattern

Now the Gang of Four, since they were kind of the first ones doing this, they were able to describe what does a pattern actually consist of. There's four basic elements and this again is something that has moved on to other pattern descriptions through the years.

The first one is the pattern name. So, this is a unique way of referring to the pattern. Hopefully, it's something that describes either what the pattern does or the problem it's trying to solve. It also is not something that would be ambiguous in our industry. Now since the Gang of Four were kind of the first ones out there, they got to pick some pretty simple names, things like bridge and observer and adaptor.

The patterns that are coming up after that, a lot of times we have to have a little bit longer names to keep them unambiguous. So, we end up with cool names like MVC, Model–view–controller or MVVM, Model–view–viewmodel, or IOC, Inversion of Control. A lot of times the pattern names that have come after that had to have been a little bit more descriptive just because all of the easy names were taken.

In addition to the pattern name, obviously the pattern has to describe the problem that it's trying to solve. Again, this is that thing that occurs over and over again in our environment. We'll be looking at some examples of this as we go along.

The third thing is the solution to the problem. Again, this is the core of that solution. It doesn't give a specific implementation. Now it turns out that most pattern catalogs will provide some code for us to look at because of course we're programmers and it's easy for us to think in code, but we don't want to think about that as the only way to implement the pattern.

What's more important is that we're staying true to the spirit of the pattern and the different parts that are described. How we actually implement it, it's up to us. Now definitely, we should use solutions that are already out there if they fit in our environment. But if our environment is a little bit different, it is okay to create your own solution to one of these problems.

Now the last thing that's part of the design pattern is something people don't like to talk about much and that's the consequences. Usually when we're having those day-to-day conversations, someone might come up and say, "Well, I was using the factory method pattern here and it was brilliant. It did all these awesome things that I needed exactly right for my code." But just like all of our other tools, our design patterns have both pros and cons. They have the solution to a particular problem but usually, there are some consequences that come along with that.

Now those consequences aren't usually showstoppers. They're not things that say, "Oh, I better not use this pattern because it's got this huge problem." Usually, they're just things that we need to keep in mind when we do implement the pattern so that we don't get ourselves into trouble. Again, we'll see some of that as we look at some examples today.

The Gang of Four Patterns and Categories

Now I mentioned that the Gang of Four described 23 design patterns and here they are. We'll be specifically looking at three of these patterns today because actually again, like I mentioned, as a developer I have used a bunch of these patterns just accidentally. So, we'll just picking out three of them specifically to see how we've been using them.

Now, the Gang of Four actually put these into categories. So, there's actually a set of patterns that are known as the Creational Patterns. These have to do with how do we instantiate an object or how do we get our objects into our application itself.

Then there's also a set of Structural Patterns. These have more to do with how do our pieces fit together? We've got these different pieces and can we put them together in different ways or somehow figure out different ways to present our objects in a way that makes sense?

 

Then the third category is the Behavioral Patterns. This just describes how our objects might behave in certain instances. Again, these are all designed to give a solution to a certain problem in our environment that occurs over and over again.

Like I mentioned, the Gang of Four book, it's really, really important. I would encourage you to read it at some point in your career, but I would not use that as a starting point. Like I said, the reason for that it is rather academic. If you're a hardcore computer scientist, you might really love it. But if you're just a developer who's just trying to get code out the door to make your users happy, it might be a little tough to read.

My copy is actually from 2008. That's when I got my copy and put it on the shelf to make me look really smart. I actually tried three different times to get through the book and it turned out, I just wasn't ready for it yet in my career. Now, when I did get through it again, it was really important. It's been extremely useful to me since then, but it is kind of hard to get started. 

The Book Head First Design Patterns

Now, if you're brand new to design patterns, I would highly, highly recommend this book, Head First Design Patterns from O'Reilly.

Now, the reason I give book recommendation is because that's how I learn best. I love books. I absorb books. They are really helpful to me. So if you're not a book person, there's lots of other resources out there, but this one is excellent. The thing that I like about this is that it actually covers 12 of the Gang of Four patterns. So, it takes 12 of those 23 patterns and it actually starts with the Gang of Four description itself.

It's not like it's trying to come up with something new. It's not trying to describe some new idea of what patterns are. It's just taking the Gang of Four patterns and describing them in a way that's a little bit easier to absorb. The Head First Design Patterns, the Head First series is all about how do we get information into your head in a way that we can understand. So, it's an excellent, excellent resource for that.

Alex:

By the way, I remember it has also samples and I think all the samples are in Java language. Is that correct?

Jeremy:

Yes, that is correct. All of the samples are in Java in this book. It actually mentions it in the introduction that if you're a C# programmer or another curly-brace language programmer, you'll have no trouble following along and that was actually my experience. But if you are specifically saying, "You know what, C# examples would be way, way better for me," there's tons of people who have created these samples in different languages online. So you will be able to find these examples in C# if that's what you really need.

Alex:

Okay. Thanks.

Jeremy:

Yeah. In fact, really the only thing that I ran into in this particular book is they had one that was specifically oriented towards JavaBeans. That's a little more specifically to the Java environment, but understanding the concepts was not difficult.

Alex:

Right. Okay. Okay, cool.

Jeremy:

I've told you here's what patterns are and I've showed you a book that I've told you not to read yet. I've showed you another book that says, "Hey, this is a good place to start." But again, if these things happened way back and started in 1994, aren't they relevant? Do they still matter to me? 

Why Care about Design Patterns?

Why should I care about these as a developer? The answer to that is there're several reasons. Again, these are things that have seen in my own career and why I just love talking about design patterns.

The first one is that these are well described solutions. People way smarter than me have been thinking about this for a long, long time. So, rather than having to come up with my own solutions to the problem, I can rely on somebody else who's already thought about it. Again, there's a lot of implementations out there as well.

The other thing is that this gives us a shared vocabulary as developers. Now pretty much every industry has its own secret language. So doctors and lawyers have all their own secret words that normal people don't understand. This is actually the secret language of developers. So we can talk in the hallway and say, well yeah. I've got a facade over here and a mediator over there. It's like talking in code.

Now, I like to think about it that way, but it's actually more useful than that because it gives us a very concise language that we can use to speak to each other. It's not just a secret code. For example, I could come up to you and say, "Well I have this one object. When it changes state, it actually sends out a notification and I have this other object that's subscribed to that. So, it receives a notification whenever the state changes," or I can say, "I'm using an observer here."

A lot of times when we're talking to other developers, maybe we're trying to work through a problem, it's not usually specific lines of code that we're having problems with. It's usually that we're having problems with the bigger concepts and how they fit together. So if I can say that I'm using an observer rather than describing a particular implementation, now I can have that conversation stay in that design area that I want it to be in. Something that I love in my world, because of that language is that it does let me stay in design mode longer.

I'm one of those people who just loves the whiteboard. I don't do heavy, heavy design upfront, but I like to know where my code is going. So, here's the big pieces. Here's how they fit together. I had an awesome manager when I was working at this particular corporate job because whenever she would walk by my desk and I would have my feet up on the desk and I was just staring at the whiteboard not doing anything else, she knew I was working because as a developer, my job isn't really to type as much code as I can. My job is to actually solve problems.

So, there's a lot of thought that goes into that. Again, patterns let me figure out how do these big pieces fit together, how do we make them work, and how can I get this into my particular application and make my users happy because in my world, it's all about making my users happy. If I'm not making their lives easier, then I'm completely failing in what I do.

The last benefit when we start using design patterns in our every day speech is that it will hopefully encourage other developers to look into them as well. So, if you're having a hallway conversation and you're like, "You know what, I was using the mediator here. It was a perfect thing for this particular problem that I had and here's the implementation I used and it actually solved the problem." If there's another developer that's overhearing that conversation, they might say, "I'm not sure what the mediator pattern is, but maybe I should look into that."

It just will spread the use of this design pattern language just through our industry as new developers join all the time. That's a huge part of it because our industry is doubling in size every five years. That means that half of all developers out there have less than five years experience. If you're a senior dev like me who's been in the industry for a while, it's great to think about all the new people who are joining and how do we get them up on board and get them to a great productive place like I have been for a while?

This is what design patterns are and why we should care about them, but really where I want to spend the rest of the time is looking at how we as developers are already using these patterns even though we don't realize it. I'm going to look at three of the Gang of Four patterns. We'll see, you know what, how we're using this and once we recognize it now, we can use it more intentionally.

Observer Pattern

The first pattern we have is the observer pattern. Like I mentioned, the Gang of Four descriptions can be ... They're not difficult to read, but you do have to stare at them for a little while. Here's the Gang of Four description of the observer pattern. "Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically."

Do you know what that means? All it means is a publish–subscribe relationship. That's what the observer is. It's describing a publish–subscribe relationship. As an example in the real world I'm going to point to everybody's favorite time waster which is Twitter and in particular, the follow functionality in Twitter. If you follow me on Twitter, you actually become an observer of me. When I change state, meaning I publish a new tweet, you're automatically notified of that. That's all it is. The observer pattern is simply a publish–subscribe relationship.

Let's go to some code and see how we actually use this in our day-to-day coding practices. The code is all available on GitHub. I'll have a link on the last slide so you can go download that. If you look at the solution that I have here, it has a set of five different projects that describe different patterns. Like I said, we have time to look at three of these today. If you want to get some bonus content, you can download the code and take a look through it.

I'm going to start out by looking at the observer pattern. Now, before I write any code, I want to run this application because I want to show you my amazing UI development skills. I'll give you a second to take that in because I know it's a little overwhelming. What we have here is a button which doesn't do anything when we click on it. There's a couple of text blocks on there that don't have any content at the moment. Well let's go ahead and fill in some code and we'll see how implementing an event handler is really an example of the observer pattern.

I'm just going to go to the code behind my form and rather than hooking up the event handlers using the designer, with the properties, we'll do it in code. My button is called ClickMeButton. So I just have to say ClickMeButton.Click. Then I say plus equals, and Visual Studio says, "Hey, it looks like you're trying to hook up an event handler. Would you like me to create that? If so press tab." Yes please. "Do you want to call it this?" No. Let's go ahead and call this observer one and hit enter.

I just love things that do this for me. Visual Studio has awesome, awesome stuff built into it. Now, in this case, I just don't want to hook up one observer. I want to hook up three. I'm just going to duplicate some code here. We'll have an observer two and observer three and we'll just copy this method down. I've got an observer two and observer three.

Now in this observer one code, I'm just going to set the TextBlock1.Text to hello from Observer1. Down here in the second one, I'll set TextBlock2.Text to hello from Observer2. Then way down here at the bottom, we'll switch things up a bit and we'll do a MessageBox.Show and we'll say hello from Observer3.

Now hopefully none of you are baffled by this code, and that's really the point because what we're looking at is we're looking at things that we do all the time. When I run this application, hopefully there are no surprises. If there are some surprises, then I'm going to get a little depressed about my programming abilities, but when I click on the button, oh look at that. Our two text blocks built in and we also got the message box popup.

But we've also used an implementation of the observer pattern. We have actually set up a publish–subscribe relationship. In this case, the state that we're subscribing to is the click state of the button. Whenever the click state of the button changes, all of my methods in this case get notified, "Hey, this has changed. Go ahead and run your code." That's really all there is to implementing the observer pattern.

Now what's interesting about this is that there are a lot of different ways that we can do this. Since it's no longer 1994, our languages and frameworks actually implement a lot of these patterns for us so that we don't have to worry about it. For example, if we're talking about the observer specifically in the C# world, obviously event handlers are out there and hooking up an event handler is one of the first things that we learn as developers. You do that hello world with your first form application and you click the button and there you go.

Creating an event handler is not all that much more difficult than that. So, it's something that developers can do really, really easily. But the thing is we might look at our problem and say, "You know what, an event handler isn't the right solution for this. I know it's built in and it's there. If it works, great. I don't have to write any extra code. But if it doesn't fit our scenario, we can look elsewhere."

There's something called an event aggregator. I first ran across this concept with the Prism framework. Prism is a framework that's designed to work in the XAML world. There's this concept of event aggregator. When you use this, the publishers and the subscribers don't have to know anything about each other. That's a benefit because I can have publishers and subscribers completely separated.

So, all each object needs to know about is the centralized event aggregator. So an observer, a subscriber, all they have to do is hook up to the event aggregator and say, "Hey, please notify me if this particular event happens." In fact, you might even say, "You know what, notify me if this event happens and it has this particular value in the payload." It can get kind of interesting with what you do with that.

On the publishing side, again the publisher goes to the event aggregator and says, "Hey, I would like to publish this event please and here's the payload that you should use for that." Again, the publishers and subscribers don't have to have any direct connection.

Now you might also say, "You know what, that doesn't work for me either." Well, starting in .NET 4.0, we got two new interfaces, IObservable<T> and IObserver<T>. These are just shells. They're frameworks that we can use to fill in our own methods that says, "You know what, here are some ethics that you can use to implement your own custom observer." You might even say, "You know what, this doesn't work for me either."

That's the thing about design patterns. We're not locked into a particular implementation, but once we recognize the problem and I say, "You know what, I have this publish-subscribe problem. What do I do?" Well, I can say, "You know what, event handlers are built in. Will that work for me?" That way, we don't spend time spinning our wheels coming up with custom code when we can go look for solutions online or inside our own frameworks themselves.

Alex:

Okay. I was just wondering are there any consequences of observer pattern because we just looked at the implementations, but usually there should some consequences or maybe some downsides or?

Jeremy:

Yes. There are always consequences. Again, with every tool that we have, there's consequences. Let's just go back and look at our code and see if we can think about what those consequences would be in this case. When I'm using the Observer pattern, something to think about is I might never get notified at all.

So, it's possible, let's just rerun this application, that I have this application and nobody ever clicks the button. Now for our simple example, that's not really a big deal, but let's say we were creating a stock ticker application that was getting communication from some service that was providing us with values of different companies.

Well if we never get that first notification, well what are we going to do? Well, we might decide we put in the default message or something like that or we might have something that says, "Hey, we haven't received any data yet just to let the user know what's going on." Again, it doesn't stop us from using the pattern, but it's something to keep in mind.

Another thing specifically with the observer is that we don't know how frequently we're going to get notified. I might get notified once an hour. I might get notified a million times a second. I don't know. Now in our particular application, we kind of have a limiting factor because our message box is a modal dialog so we have limited how quickly we can handle things in this particular application, but again it's something to keep in mind.

Then the other thing is that we don't know how frequently we'll be notified. Did I say frequently or often? They're so related. I might get notified one time or I might get notified a million times. Regardless of the total numbers of notifications I get or how close together they are or how spread out they are, those are things that we think about with the observer.

Alex: Okay.

Jeremy:

It would be nice if things came for free. But then again if we didn't have to judge the pros and cons of each of our tools, they wouldn't pay us the enormous amounts of money that they do to be programmers. I hope everybody is paid enormous amounts of money. That's the observer pattern. Again, it doesn't have to be complicated. Now obviously the situation that I showed was pretty simple, but it's something that we can think about in the future. "Hey, I've got publish-subscribe. What do I do about it?"

Proxy Pattern

The next pattern I want to look at is the proxy pattern. Here's the Gang of Four definition, "Provide a surrogate or a placeholder for another object to control access to it." Now for this, I'm going to use a legal concept from the U.S. which is where I live, and it's called power of attorney. My brother actually lives in Bamako in Mali, West Africa. I live in California on the West Coast of the United States. Now, he has assigned me power of attorney, which really makes me his proxy.

What that means is let's say someone wants to do business with my brother. Now, they could figure out well okay, how do I get this papers over to my brother in West Africa to sign. Unfortunately, U.S. has some kind of archaic laws. Like a fax signature is legal. So. it's like okay, well let's fax them over and he can sign them and fax them back. Of course, the first thing you have to do is find a time machine so you can go back to 1996 to fax something. But another option is that this person could have me sign the documents as my brother's proxy. That in the U.S. is exactly the same as if my brother had signed those documents himself.

As his proxy, I can work on his behalf, and to the individual interacting with us, interacting with me is exactly the same as interacting with my brother who is 6,000 miles away from where I live. That's actually a pretty common implementation when we're talking about the proxy pattern in code. A lot of times we're dealing with a network resource.

In this case, I want to show an example of working with SOAP services. Now, I know SOAP services have gotten a bad wrap recently because people are like, "Oh, REST is the trendy thing to do. You should be doing that. SOAP is archaic. You should never use that. REST is the replacement for SOAP." To that, I say, no. Both REST and SOAP have their pros and cons just like all of our tools. I love that we have more tools in the toolbox, but let's see which ones are great for certain things and which ones are great for other things. Rather than replacing my tools, I just want to make my toolbox bigger.

Now in the case of SOAP services, what's awesome about this is they're self-describing. What that means is that my development environment, in this case Visual Studio, can actually create a proxy object for me. If you've used a SOAP service in .NET, you've actually used an implementation of the proxy pattern.

Let's take a look at the service that I have. You can see it's really exciting. It just has one method called GetPeople and it returns a list of person objects. If we just peek at this, we'll see that the person class is pretty simple. It's just the first name, the last name, a start date, and a rating. That's just the shape of our data. Then in this case, I just have a hard coded collection of objects that it's returning. So, I'm not even going to database or anything like that. This will provide us with the data that we can use in our UI.

Now before we look at the UI code, let me just go ahead and run this application because again I want to you to be amazed with my UI skills. This time with have a button and a list box. Yes, I know we're moving up in the world. Again, the button isn't doing anything at this point in time. Now the advantage of using the WCF SOAP service is that I can have Visual Studio generate a service reference for me, which is really creating a proxy object.

For this, I just right click. Inside the project where I want to use the service, I say add service reference. In this case, I can click the discover button and that will find all of the services that are in my solution. I can say, "Oh yeah. Here's this one here. Is this the one I want?" Yes. It has that GetPeople method in it. I can just fill in the rest of this and click okay and it will stab out all of the things that I need. Now I have already done that in this project, so I won't do it again but let's see how we actually use this in the code.

Again, we'll go ahead and go to the code behind of our form. Again, this is just the form that has the button and the list box on it. Now, all I need to do is new up an instance of this proxy object that Visual Studio created for me. So I'll say var proxy = new PersonServiceClient. That's just the name Visual Studio gave to my proxy class. Then if I say proxy., you'll notice that I have a GetPeople method exactly like I have on the service object.

When I look at this, I see this returns a list of person objects. Okay. List<Person> people = proxy.GetPeople. That looks like I need a using statement for bringing in the collection. Then all I need to do is get this into my list box. Well in this case, I have something called a PersonListBox that I can just say it's ItemSource equal to what's coming back from this. When I do this and run my application, again hopefully there's no surprises, we click on the button and we'll see that our list box actually populates.

Now, that's not very impressive because this code looks pretty normal to me. But the thing is once we start thinking about what's going on behind the scenes, now this becomes more important because if I want to call a SOAP service, what actually has to take place? Well, first of all, SOAP is XML based. To create a SOAP request, I have to make this big ball of XML in a specified format. Then I have to send that SOAP request across the wire usually by HTTP. Then I have to wait for a response to come back. Then I have to retrieve the response, which again will also be by HTTP.

Then I have to parse the response that comes back because it's actually a SOAP response which is a big ball of XML. Then I have to take the things out of that that I need and turn them into C# objects that I can actually use in my code. This is what I have to do with a SOAP service, or I can use the proxy class that my IDE generates for me.

Let's take a look at the service itself. Again, this just has a single method. Let's pretend this wasn't a service. What if we were just using this directly. How would I use it? Well, I would new up an instance of this person service class. So new person service and then I would call Service.GetPeople. That's how I would use it directly just to use that GetPeople method on an instance object.

How am I using this proxy object? Well, I'm newing up an instance of person service client in this case, which again is the proxy, and then I'm just calling proxy.GetPeople. So, I'm interacting with this remote resource exactly the same as if it were a local resource. Again, that's very, very powerful. Again, this is one of the things that I really love about SOAP services is that they are self-describing.

Now the Gang of Four actually, something that's interesting, is the example that they use for their example of the proxy and that is well, let's say you have this picture. Back in 1994, our networks were really slow. So if I just wanted a photo to come across the wire, it might take 30 seconds to a minute, and that would be for an extremely low resolution picture compared to our current standards.

So they said well instead of doing that, what if you create a placeholder in your application rather than bringing down that big resource off the network. Then if somebody clicks on that, then you can go through the process of retrieving the object itself. At first, I thought, well nobody has got that problem anymore. Our networks aren't that slow. I'm just laughing about how long it takes for a picture to come across the wire, but then I started thinking about our mobile devices.

Yes, we like to think that our mobile devices have high speed connectivity everywhere, but at least in the U.S. I ran into big chunks of country that have very little connectivity. So I might stop along the side of the road to take a break and pull out my phone to check Twitter and my connection says 2G. I'm like 2G? I haven't seen a 2G connection for years.

I'm trying to look at Twitter, but Twitter is just eagerly downloading all of the images because that's what it normally does. It's like well, maybe this application should be more network aware and say well, if you're on a constrained connection, maybe I should put placeholders and only download things when you actually ask for them. Those are things that we can actually use in our current day-to-day operation.

Facade Pattern

Now I do have one more pattern that I want to go through and that's the facade pattern. Again Gang of Four description, "Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher level interface that makes the subsystem easier to use." All this is talking about is wrapping a complex API and making it easy to use.

As a real world example, I'm just going to talk about my home entertainment system. Now, I'm one of those people that's got multiple remote controls pointing to multiple pieces of equipment. If I want to play a DVD, I have to turn on the TV if it's not already on. Then I have to set the input to HDMI 1. Then I have to turn on the stereo if it's not already on and make sure the stereo is set to Aux input. Then I have to turn on the DVD player if it's not already on and press play on that.

Now this is absolutely no problem for me because I'm a couch potato and I can reach over and find those buttons on the remote controls without even looking. But the problem is is that I also do a lot of travel and I have two cats that don't do a lot of travel. So, I have a friend that stops by and checks on my cats when I'm out of town and for whatever reason, she likes to watch DVDs with the cats.

I don't want to try to teach her how to do this complex subsystem. So, for that, maybe I need a universal remote control, and there's just a button on there that says play DVD. It's up to that universal remote to figure out okay, what do I need to do to make this actually happen? That's really all that the facade pattern is. Wrapping something complex, making it easier to use.

Now as far as coding is concerned, if you‘ve used a foreach loop, you have actually used an implementation of the facade pattern. I love foreach. Foreach is just one of my favorite things out there because it seems like I'm constantly iterating through stuff. Let's just take a look at this.

This application will look familiar. It's a button in a list box. Again, right now the button is not doing anything. If we look at the application itself rather than accessing a service, I just have a hard coded class here that does the same thing the service did. It will just return the hard coded list of these person objects that I can use.

If I flip to the code behind, what I see is that I'm already calling that GetPeople method and I'm using an IEnumerable<person>. Now IEnumerable is an interface that's pretty much on every collection in .NET. It also shows up in a couple of interesting places. Anything that uses IEnumerable or that implements IEnumerable, we can use in a foreach loop.

So I can foreach over this and say foreach (var person in people), PersonListBox.Items.Add(person). I can just iterate over that because the IEnumerable describes that and foreach makes it really easy to use. Now when I click on the button, my list box is populated.

Now like I said, foreach is actually is a facade. It's a wrapper around IEnumerable itself. Let's just comment on that code and see what it would be to use this directly. If I look at the people object and say people., in addition to the stuff that we get from object, there's a method called GetEnumerator. This GetEnumerator will return me an IEnumerator<person> which we'll call enumerator.

Then once we have this enumerator, this is the thing that we can use to kind of loop through things. If I say enumerator., we'll see we have quite a few things that we can choose from. First is MoveNext because when we're talking about something, we can enumerator through. All we're doing is saying, "Hey, give me the next one. Give me the next one. Give me the next one. Give me the next one. Give me the next one," until there aren't any more normally.

In addition to the MoveNext, there's also a current property and that will be whatever the current item is that I just moved next to. There's also a dispose because this implements the IDisposable interface. Then there is a reset, so the reset will go back to the beginning of this enumeration so that we can start over.

If we look at MoveNext, this doesn't return the next item. Instead it returns a boolean value, a true false, and that lets us know if that MoveNext was actually successful. Well, that looks like something really awesome to do in a while loop. I can say while MoveNext. Then inside the code, I can say PersonListBox.Items.Add and I can say, enumerator.Current. That will actually give me the current item that I'm on after I move next.

If we run the code in this state, we'll see we get exactly the same functionality which is that my list box is populated after iterating through these objects. So, foreach actually takes this code and wraps it into a way that's easier to use. It actually goes a step further because like I said, the IEnumerator also implements IDisposable. I'll probably want to wrap this up in a using statement so that when I create it I also make sure that dispose gets called properly.

The thing is if I'm one of those nerdy people that looks at IL, the code that's generated by this code here and the code that's generated by the foreach is actually exactly the same in the IL. So the foreach is in fact just a wrapper of facade around this code.

Alex:

Well, we know we can go even somewhat deeper, a bit deeper and we'll see that using I think can be called also a facade, right?

Jeremy:

Yes.

That's actually absolutely right because what using does is that it makes sure that dispose gets called regardless of whether there's any exceptions. So if you actually look at the code that's generated by using statement, it creates a tri-finally block and it makes sure that dispose is called inside the finally. So yes. That's a facade around a more complex infrastructure as well. These are all things that make our code easier to code and easier to use. Now, when we're talking about consequences to the facade, not all of the members are necessarily exposed. So we thought there was a reset method on the enumerator. There's no way to access that reset method when we're in a foreach loop, but quite honestly, generally what I would do is just spin another foreach loop and start over again. So a lot of times those consequences, again something to keep in mind, but not necessarily something that keeps us from moving forward.

Summary

Those are the three patterns that I wanted to focus on today to show us that you know what, we're already using this. If we look at design patterns, again these help us solve problems that occur over and over and over again in our environment. Again, it's just the core of the solution. It's not giving us a particular implementation. In fact, it describes it in such a way that you can use the solution a million times over without ever doing it the same way twice.

Now again, I would not recommend that because we should not be reinventing the wheel, but once we understand design patterns, now I can say, "You know what, I need an observer. So rather than building my own observer, let me go online and see what other people have done and if I can use that, awesome. But if I can't, you know what, maybe I'll take a wheel and tweak it a little bit."

Again, why do I care about this? These are well described solutions from people who are way smarter than I am and I just love to leverage their code so that I can move forward more quickly. It's a shared vocabulary that gives us a very concise language. Hopefully right now if I say I'm using the observer pattern you know what I'm talking about. Even if you don't know a specific implementation, you kind of know the big pieces that are there.

Again, this allows me to stay in design mode longer, and I really love that because now I can think about the pieces and how they fit together. Then of course, if I start using this in my every day speech, hopefully it will encourage the other developers around me to use it as well.

That's what I have for you today. Again, here are some links that you can get to the Design Patterns On-Ramp course on Pluralsight, as well as the code samples on GitHub. If you follow the GitHub link, there's also some links to some articles and other things as well. With that, let's see what our questions look like. Alex, have you been keeping track of those?

 

Q&A

Q: Is there some restriction implementing patterns in JavaScript?

A: Well, there are different patterns that are using in different environments. For example, the Gang of Four patterns are very much geared towards the OO world. In the functional world and other worlds, there are different patterns that are talked about. JavaScript is one of those interesting languages because we can kind of treat it like an OO language even though it's not and we can kind of treat it like a functional language as well. So it really depends on the approach that you're taking.

There, I would say, yes there are definitely patterns that are useful in that world and I'm sure there is ... JavaScript is not my world so I'm not going to talk about any specifics, but I would say yes, there are definitely patterns out there in that world as well.

Q: Is copy-paste also a design pattern?

A: Copy-paste actually is anti-pattern. I also have a talk I do on clean code. I talk about how copy and paste is generally evil because it causes us problems. In fact, I don't even call it copy-paste in my normal development. I call it copy-pasta because if you do it enough times, you will end up with spaghetti code.

Q: Should we say that facade is an example of obstruction or something like that? 

A: That would be something I would need to think about a little bit more. I guess it could be considered a form of obstruction, but it's more of a wrapper. I would have a tendency to say wrapping rather than obstruction because when I think of obstruction I think about things like interfaces. I love interfaces. I have a whole Pluralsight course on interfaces. Those can help us with loose coupling, things like DI and that kind of thing.

This is one of actually those gray areas. It's actually an interesting topic because I'll often get asked is X an example of the Y pattern? That's where we have to stop and think about what's the spirit of the pattern. What is trying to accomplish. In that situation, obstruction actually isn't a design pattern in that case. It's more just a programming concept, but it's kind of that same thing. It's like what are the goals of obstruction and what is it trying to do? My gut instinct is to say no, but it's a gray area. It's one of those things that we can have great discussions with each other about.

Q: Does the usage of foreach have disadvantages in performance in comparison with using the reset method, what you talked about in this example?

A: It has absolutely no difference. Again, I'm kind of one of those nerdy people who likes to look at the IL code that's generated by the compiler. Again, the code that I showed using enumerator with the while loop and the MoveNext and all that, that is exact. If you look at the IL, exactly the same code is generated between that and the foreach loop. So there's absolutely no runtime differences at all. I would guess there might be a compile time difference, but it's probably one of those things you wouldn't notice.

Q: Out of all the design patterns, how does a newbie decide which patterns to use for a given problem1? In other words, is there a way to filter out the patterns to arrive at a subset of suitable pattern?

A: This is a difficult question to answer. There are multiple ways to solve a problem. And there are also multiple design patterns to solve a single problem. The differences in the pattern have to do with what approach is taken. And this often leads to a different set of consequences. I would start by understanding the Gang of Four patterns. These are very common problems/solutions. And it will help understand the more complex patterns than you might run across. Just like learning anything new, start with the basics and talk to people or look online to see what people who are working in the same problem-space are doing.

Q: Does design patterns always obey SOLID principles? Or is it even important to do so?A: The SOLID principles are “best practices” in the object-oriented programming world. I don’t like to use the term “best practice” because that sounds like it is always the right answer. But with my experience (but success and failures), I’ve found that they are a good place to start. If I have a reason to not use the practice, I’m okay with that as long as I understand the pros and cons of a particular situation. In general, the Gang of Four patterns can help us adhere to the SOLID principles, but it all comes down to how we use them.

Q: Any example of factory or abstract factory which we are using and not aware of?

A: Unfortunately, I can’t think of one off the top of my head. But I have use the Factory Method to dynamically load objects from the file system. If you’d like an example, you can see my materials on C# Interfaces: http://www.jeremybytes.com/Demos.aspx#INT.

Q: Isn't Proxy pattern built-in pattern with tools like Visual Studio?

A: The implementation of the Proxy pattern that we looked at (accessing a SOAP service) is definitely built in to Visual Studio. But there are other scenarios we might want to use the Proxy, such as using a thumbnail image instead of bringing down a full image or the difference between downloading a song and streaming a song. So we do have certain implementations of patterns that are built into our language and tools. Some other examples in C# are Iterators (IEnumerable) and Observers (Event Handers / IObservable).

Q: How do we know that we need to use design patterns to a specific problem? Because most of the problems can be solved without using any design pattern.A: Learning about design patterns helps us see what solutions are available (and hopefully we can borrow someone else’s solution rather than creating our own from scratch). We can build a house by stacking bricks, but if we understand the patterns of walls, lintels, and foundations, we’ll end up with a much better structure. Programming patterns are the same way. I spent many years using patterns accidentally because I ended up solving these common problems. But once I could put a pattern name to a problem, I could look at how other people implemented the pattern. Sometimes I use those solutions, and sometimes I used them for ideas to incorporate into my own solutions. But that lets me use much better than what I could come up with on my own.

 

Q: There are plugins which allow patterns to be implemented in Visual Studio. Would you advise using them or rather learn the codes and implement them?A: I haven’t used the tools, so I can’t give an informed answer. As a general rule, I like to understand what the tool is doing before I use it. For example, I use Dependency Injection (DI) containers when I code, but I was not able to use them effectively until I understood what the containers were doing – and more importantly why. I would think it’s the same with pattern tools. I want to understand the patterns (particularly the “why”), and then I would be fine with letting a tool do the hard work for me. This would be similar to how I let Visual Studio create the SOAP proxy for me. I don’t need to understand all of the details (XML, HTTP, etc.), but I do need to understand why I’m using the proxy.

 

Q: What pattern should I use for creating exception handling library?A: Exception handling is a pretty big topic. It turns out that the built-in exception handling in .NET uses the Chain of Responsibility pattern (this is one of the examples I show when I have a bit more time to talk about patterns). When an exception is thrown, it looks for a catch block that can handle it. If it can’t find one in the current method, it walks up the call stack to the calling method. Then it just keeps walking up the call stack until something can handle it, or it drops off the end. (And this is why it’s a good idea to put a global exception handler somewhere in the code to make sure the user has a good experience.)

 

Q: Instead of using Proxy pattern for WCF services, I prefer use ChannelFactory object to use same object from the service without any MAPPER. Is there any other way to use Proxy for this case?A: As we saw in the definition of design patterns, there are a million different implementations. If there is a built-in implementation (such as the WCF Proxy in Visual Studio), I like to start there since it’s “free”. But if I find that my needs are a bit different (like I want to optimize for speed), then I’m free to look for different implementations or create my own. So there are lots of ways to use a Proxy in this situation. Unfortunately, I haven’t looked into them since the built-in one has worked for the situations I’ve needed.

 

Q: What about structure diagram and code?

A: Often when patterns are described in pattern catalogs, they are accompanied by a UML class diagram. Personally, diagrams often cause more confusion for me than help, so I tend to not use them. It’s easy for me to look at a class diagram and get stuck in a particular implementation when I really would rather understand the spirit of the pattern and the concepts behind it. Both the Gang of Four book and Head First Design Patterns include class diagrams (although the Head First book uses them for specific example code rather than the overall pattern).

 

Q: What pattern should I use for micro service implementation?A:Micro-services is a big topic. Looking for *a* pattern is like looking for a pattern for a web site. Generally, we would use multiple patterns to address the different problems that we are trying to solve. If we think of each micro-service as a self-contained application, then we can imagine using quite a few different patterns in putting it together.

 

Q: What is the difference between proxy and facade?

A: The main thing about design patterns is to look at the problem they are trying to solve. One way to think of the Proxy pattern is as a way to access a remote resource as if it were a local one (it’s a bit more general than that, but that’s the example we saw with the SOAP proxy). The Façade pattern is a way to reduce complexity by creating an easier way to interact with something (as we saw with the “foreach” example). The implementation of the SOAP proxy can also be considered an implementation of the Façade pattern since it’s wrapping the complexity of making the SOAP call (XML, HTTP, etc.). This is part of the fun when we start looking at patterns. We find that complex systems are often a combination of multiple patterns.

 

 

Q: When I have multiple patterns that can be used to solve a problem, how can I choose one, or can I combine them?A: This is one of those areas where we try to understand our tools better. There are multiple patterns that address the same problem (for example, there are many patterns that are variations of the Gang of Four patterns). In that situation, look at what the pattern is optimizing for. It may be addressing a particular consequence, such as performance or memory usage. If you are concerned about that consequence, then it may be a good choice. But if that consequence isn’t important to you, then something else may be better.

Q: Taking into account the example of IEnumerator and foreach, what would be the most correct to use?A: Since “foreach” gets compiled into the same code as using “IEnumerator” directly, I would use foreach. This makes our code more readable – and we need to make sure our code is readable by humans in addition to the computer. If there were a difference (for example, if the direct use were faster), even then I would look very carefully to see if that difference is important to me.

Q: You said foreach is a facade pattern. Is it also an iterator? Does it mean that any concrete implemenation can be a combination of multiple patterns?A: Yes, foreach is an example of the iterator pattern. In fact, I talk about this when I have more time to talk about design patterns. Many things we run across are implementations of multiple patterns. Another example is data-binding. This implements the Observer (when the UI elements change, the backing objects are changed) and also the adapter pattern (when a backing field is a number, it is displayed in the UI as a string). In reference to “foreach”, I usually call this an ‘Iterator” since that is its primary purpose – to iterate over items. The “Façade” pattern is more an implementation detail than the primary purpose.

Q: Which design patterns are useful in writing cross-platform code?A: There are a lot of patterns that we can use in cross-platform code, just like there are lots of patterns we can use in any application. The patterns we use depend on the needs that we have. For example, if I wanted specific UIs for each platform and wanted to share presentation code, I would look at various patterns that could help with loose coupling, such as Abstract Factory or Inversion of Control. But these aren’t strictly limited to cross-platform concerns.

 

About the speaker, Jeremy Clark

Jeremy Clark

Jeremy Clark makes developers better. By drawing on over 15 years of experience in application development, he helps developers take a step up in their skillset with a focus on making complex topics approachable regardless of skill level. He is a Microsoft MVP for .NET, and he has authored seven courses for Pluralsight, including "C# Interfaces", a course aimed at giving developers a clear understanding of abstraction. He loves speaking and has delivered over 200 technical presentations in the last 7 years in the United States and Europe. Jeremy lives in Southern California with 2 cats and a banjo. Jeremy's blog.

 

In this webinar, PostSharp’s founder and principal architect Gael Fraiteur demonstrates some of the most exciting new features of PostSharp 5.0:

  • Logging: PostSharp 5.0 comes with a fully revamped logging aspect, which allows for much more flexibility than before. Key new features include complete customizability, support for semantic logging, and super-fast performance.
  • Caching: You can now cache method return values and invalidate the cache easily, with custom attributes. PostSharp 5.0 will include support for MemoryCache and Redis, two-layered caches, and local caches with pub/sub invalidation.
  • Async methods: We have filled the gaps in OnMethodBoundayAspect and MethodInterceptionAspect for async methods.

Watch the webinar and see what's coming up in the new version:

PostSharp 5.0 Sneak Preview Logging, Caching and Async on Vimeo.

Download source code of the examples.

About the speaker, Gael Fraiteur

Gael Fraiteur

Gael has been passionately programming since childhood; building and selling his first commercial software at age 12. He is President and Chief Architect at PostSharp Technologies based in Prague, Czech Republic. Gael is a widely recognized expert in aspect-oriented programming and speaks at developer conferences in Europe and the United States.