Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2000-416
$eventId
ID of event: wwdc2000
$eventContentId
ID of session without event part: 416
$eventShortId
Shortened ID of event: wwdc00
$year
Year of session: 2000
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC00 • Session 416

WebObjects: Designing Reusable Components

Tools • 55:57

This session provides practical guidance on designing and packaging nested components for reuse, including API, synchronization, validation, palettes, and frameworks.

Speaker: Kelly Kazem

Unlisted on Apple Developer site

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

My name is Kelly Kazem. I'd like to welcome you this morning to Designing Reusable Components. I'll have to get used to this thing. How many people here are currently building WebObjects applications? Wow, that's cool. This session was really designed for you to give you some practical techniques and ideas for better leveraging the power of reusable components. How many people here are using Java as their primary development language? How about Objective C?

Any web script? A few? Okay. Well, all the examples that we're going to go through in this session are based on Java, but for those of you that are Objective-C programmers, I want to make sure that you understand that everything we talk about is applicable to all of the programming languages that we're going to talk about.

The topics we're going to go through, we're going to start with a basic architecture overview, talk about how you take reusable components and package them in the frameworks, show you how to put those on palettes, talk about component synchronization in depth, some state ideas for managing state between components, a cool demo on dynamic reusable components, low component content. Then we're going to finish up with some performance debugging and design ideas.

So to start this thing off, we're going to do kind of the three amigos thing. It's going to be myself and two of my associates doing the presentation, starting with Scott Sweet, who's going to go into reusable component architecture and show you how to put your components on the palettes and create frameworks out of them. Scott?

Thank you. It's interesting because I just came from Louisiana and with everybody here from international, I was there for about a week and a half and I started talking really funny because I started sounding like them from Louisiana. And then I come here and everybody's international in our engineering group. So if you can imagine all the different languages and people talking different languages all in one sentence, it would be rather interesting. I can't do it. I'm not going to try.

But anyways, with that, one of the things about reusable components and many of you probably are aware of it. First, most important is reusability. Obviously, that's the whole point. But one of the things to think about is your ability to organize those components not only within an application but across multiple applications, across an enterprise. And these are one of the beautiful things. And as you go through the session today, you're going to learn some bits and bytes about the advantages and how to make sure you use design issues. Along those things. The other thing that's really good is rapid development.

I'm going to go through an example and build some really simple components. But the idea here is once you create a group of components, frameworks of components, now when you start creating very complex applications, say like a login screen and these kinds of things, you can put a lot of functionality into those, just drag that into your application and not have to spend a lot of time coding, debugging, testing, etc.

So let's talk about the architecture. One of the things that's important to understand about a component is it can be a piece of a page or it can be the entire page. So if we look on the right hand side, I'm showing the parent component as being a full page, but inside of that we have things like header components and footer components. And keep in mind, our original baseline element is dynamic elements, right? And so with reusable components, what we're doing is taking these dynamic elements, grouping them together, and creating complex functionality.

So the header and the footer, for example, would be things like menu bar and background color and your time and your date and all those kinds of things that might be common across a lot of your single application or your enterprise. But then inside of that query component is where you're going to get a lot of different kinds of elements. So you're going to get a lot of different kinds of things that may be used across your application or specific to a particular developer and what they're using them for.

So the next question is, what's the process? How do you do this? And the first thing and most important thing, this is really very important, build and test your component in your application. Don't start with the component, put all these components into your application, you have all these bugs, and now you've got to figure out where it's coming from. So start in the application, build it, test it, make sure that it actually works, and then move it into a component environment.

So then you make it a reusable component. Again, test it again. Make sure you build a little simple app, bring that component in, wire it up, make sure it actually works as a component, and I will do that in the demo in a few minutes. Finally, put this into a framework.

This is where you're going to really get your power, because now what happens is you'll have a framework with lots of objects, and these reusable components now in that framework can be shared among all the developers. Either among your friends or what have you, across your application and so on. The next step would be to palletize them. Now with the palletizing, there's a couple advantages here. Palletizing your components.

[Transcript missing]

and then finally you're going to go across multiple applications and this is an iterative process clearly you're not going to do this just only once as you build your application you're going to find places of reuse break them out as a component put it into a framework So once you have, this is giving you an idea here of a reusable component, the top three parts should look really familiar to you since you've been through several sessions here.

The one thing that's different about a reusable component is the very bottom, which is the API file. And this is how you actually expose a particular object or a particular variable to the outside world that you're going to use for binding, and we're going to look at that a little later.

One of the very important things about the components is your synchronization. Kelly is going to spend a great deal of time about this, but one of the things that is important is that WebObjects is automatically synchronizing your parent to your child. So when you're using a component at the child level, under the covers, WebObjects is automatically taking care of that for you. And Kelly is going to get into a lot of detail of actually some of the advantages and disadvantages of automatic synchronization as well as manual synchronization.

Here's some code here just to give you an idea of communicating back up to the parent. One of the things that's neat about WebObjects is our ability to get your information at the child level via the parent rather than actually having to have an instance variable at the child level. Again, parent-child communication here. This is the way you would actually traverse that and be able to get that information.

Okay, so let's go ahead and ship to, switch to machine three, my Windows machine. What I'm going to do is real quickly create a very basic application. Now one of the first things that I want to do here is I've got a data mile settling over here and I'm just going to go ahead and add that. You guys probably know how to do that already. We've seen that through several of the sessions already.

Okay, so I have my data model. I want to do this real simple, quick stuff. Let's go ahead and create a form. Inside that form, let's go ahead and create a little text box. Let's go ahead and add a submit button there. Next thing I want to do is go ahead and add a display group.

Let's go ahead and take that display group and wire it up to my entity. And now what I'm going to do is go ahead and wire up my display group up to these two objects that I have up there. So the first one I want to do is I'm going to do a search screen, and I'm going to search on company name. And the second thing I'm going to go ahead and do is take my submit button and I'm going to put that on my qualified data source.

Alright, so I have my search screen now. Next thing I want to do is go ahead and bring in a reusable component that we give you out of the box, which is the direct-to-web stuff. So let's go ahead and add that in there. We're going to go ahead and wire this up.

And what I'm interested in looking at in the display group is an attribute called Company Name. And I'm going to go ahead and define save that. Okay, so let's just go ahead and start with this. We're gonna go ahead and compile. So while we're doing that, one of the things is that--one that you wanna check out is we gave you a lot of reusable components right out of the box.

I didn't go through all the palettes up here but those of you who are new to WebObjects, in version 4.5, we've added a lot of new stuff in the WoE extensions. Also the JavaScript stuff that I know that you folks saw--I think it was yesterday. So check it out.

Go in there, go into the examples and see what's in there so you get an idea of some of the things that we're actually giving you right out of the box so you don't go off and build them on your own. Okay, so we're going to bring up the application now. Really simple, it's nothing really advanced. Basically, I have a search screen. It's accessing my database. The direct-to-web component is going to display those values for me on the screen.

Okay, so just to see here, I'm going to go ahead and do a query to see that it's working properly. Okay, so we've got our basic app. Now what I want to do is turn that search screen into a reusable component. So that's going to be my second step. So I'm going to go ahead into my application here. I'm going to call this thing Simple Search.

I'm going to go ahead and open this up. First step, one of the most important things in doing this is make sure you create this component as a partial document. This gets rid of the body tags and the head tags. And the idea here is when a component, you've got to think about what am I dragging this into on my HTML page. And typically those tags are already there. So making it a partial document will take care of that.

Second thing is, I'm just going to go ahead and take this from my original. Let's go ahead and get rid of it there. Put it in my new component. Now one of the things I'm going to do is here I notice I have my display group is specific to the application. Well I want to make a generic one. Let's just call it MyDG. And now I'm going to go ahead and modify each of these bindings to be specific to this display group.

So that's the second step. So I've got this bound up to my component. Now the third step is exposing what I'm interested in for binding purposes when I include this into another component. So the API editor is something that's new in version 4.5. And one of the things that's really cool here is it just brings up all the different variables you'd see down here up into the API editor. So I'm going to go ahead and make my display group required. If I go click on the validation tag, one of the things that's real interesting is you can go in here and make business rules that are going to be associated with validation.

and then we click on the display here what I want to do is go ahead and put a icon what I want to use when I actually use this component Let's go ahead and save that. Okay, finally now what I want to do is take that reusable component and put it into my first application.

And we see here right away that that component is already appearing. We'll go ahead and add that. Let's go ahead and wire that up. This is the binding that I exposed with the API editor. And let's go ahead and rebuild our app. I do need to recompile because I added a new component. I also added the new display group. So I will have to actually recompile this. And now we have the same exact application now using my reusable component.

Okay, let's go back to the display now. Our presentation. Thank you. Okay, so the next step is how do I set this up so that I can actually do reusability with it. So what we want to do is we've gone through the step of actually debugging these at the application level.

We're now going to put it into a framework. We're going to do that in a couple of minutes. One of the important things with the framework is to do a step called make install. Okay, so there's one part of actually making the actual framework itself for compiling purposes, but then you have to install it into the directory that WebObjects uses when the application is actually running. And so we'll actually take a look at that. And then of course we can palletize them if we want to.

So a couple of key things for, again, for palletizing. You know, create custom pallets that are multiple ones for different developers. You know, sometimes in your environment when you're doing team development, you're going to have different kinds of developers who have different levels of expertise, and so you can use pallets as a means to break those up. So you can do that according to your skill sets. The other thing is, It also really helps you to organize things. You can create multiple palettes based on organization.

And one of the things that's really nice you'll see here is using those custom images that will show up. So rather than it just being a picture of a component and the name of it, you can put a picture on it and use your graphic artist expertise there to help you along those lines. Okay, so let's go ahead and go through that step.

So what I'm interested in actually doing at this point, let's clean this up a little bit. So I want to create a brand new project that's actually for a framework. So let's go over here into our project builder. And this is the drop down to allow you to pick and choose. So when you actually create a framework, you'll see that one of the options down here on the bottom is WebObjects Framework as opposed to WebObjects Application. And we're going to go ahead and put this in here. We're going to call this Reuse Framework.

Okay. So now when we do the framework step, It's pretty simple, easy stuff. So what we're looking for are three basic files. First thing we want to do is actually pick up the Java class that's associated with the reusable component. And that's this one right here. Let's just go ahead and drag that into my framework. The second thing that we want to do is actually bring in the component itself. So let's drag the component in. And the third thing that we need to have is the API file.

Once we have that done, we have our basic framework, we're going to go ahead and bring up the build. Remember I talked about you can compile the framework itself or you can actually do the install. And this little tag here is where you actually would see that. This is the checkbox. So we're going to go ahead and do install. One of the things that we'll do is both the compile and the install for us.

Okay, so basically I've built the framework. Now it's gone ahead and actually installed it into a directory that we're going to use in a second. So now that's that step right there. The next thing that we need to do is put this thing onto a palette so that we can actually reuse it.

So I have a palette sitting over here. Let's go ahead and make my palette editable. And I want to go ahead and bring in that component and put it onto my palette. So, in the file system here, The default directory that Apple wants to go look in is Apple Local Library Frameworks. That's where it by default will install your frameworks when you actually make them. Now you do have the option if you wish to change that, have multiple locations and so on.

and inside of here we have our component sitting here that we want to go ahead and use. Let's just go ahead and drag that on. So we have that in our palette now. And down below I have a logo that I've built, and we'll drag that on. Let's go ahead and save our palette. and make it read only. So now we actually have our component on a palette that I can reuse that's actually referencing my framework now. And let's just to make sure that this thing is actually working.

We're going to come down here and I have an application called Final. And I've already kind of pre-built a lot of stuff here so we don't have to repeat everything. Let's go ahead and bring up Main. and we see I have some of the things already wired up. And let's just drag my component in off my palette.

And one of the things you'll notice here is it's adding the framework. And I'm going to take a look at the project in a minute to understand that. But one of the things that will happen is if the framework that the component is referencing is not already in your project, it will add it for you.

And we go ahead and wire this up and save it. We'll go back to our project. And one thing, I'll go ahead and bring up the inspector. Inside of here, there's an option under Project Builder called Framework Search Order. And by default, if you go in and look in your project, you will not see this there. So it's important that if you're going to do that, be sure you go in and add that default directory so that it can reference it properly. Okay. Let's go ahead and compile our app.

We have the same component now running as a reusable component from a framework. Okay? It worked! That's cool! Okay, what I'd like to do now is to go a little bit deeper, is bring Kelly back up to go into the inter-component synchronization. Thanks, Scott. Okay, so component synchronization.

Why is it important? It's important because if you're going to create very complex components or deeply nested components, component synchronization plays a big part in how efficient those components are going to execute at runtime. Obviously, you want to build very scalable apps that run fast, and prior to WebObjects 4.0, the framework wasn't really optimized for very deeply nested components, and they added some support for that to make it a lot better in 4.0.

So basically there's two methods of synchronization. There's automatic synchronization, which you're used to now. WebObjects performs synchronization automatically between the parent and the child. There's nothing you really have to do to implement that other than declare your bindings. However, under certain circumstances, you could run into some performance issues if you have lots of bindings and deeply nested components.

The other type of synchronization is called manual synchronization. This is effectively where you disable the automatic synchronization that WebObjects will do. However, you're going to have to do a little bit more work to decide when you want to perform the synchronization and which variables you want to perform the synchronization on. And it gives you just basically more control over how it's happened.

So if we look at automatic synchronization, basically the WebObjects framework will attempt to synchronize bindings between parent and child components up to six times for a given iteration of the request response loop. So this can really add up to quite a bit of overhead if you have lots of components and lots of bindings per component. The other issue you run into is since you don't have control over when these synchronizations occur, if you have any kind of application logic in your accessor methods, those are likely to be executed redundantly multiple times, and that may be something you don't want.

So if we look at an example here, basically there's kind of three things this example wants to point out to you. And one is the fact that it's possible to Pass-in Null Values from the Parent to the Child. Textbox in the parent component, and you didn't enter any text into that, and you submitted. A null value may get synchronized into the child component, and then when you go to execute some logic on that, you're going to get a runtime exception. I've actually seen deployed apps where that wasn't caught, because they never tested it that way.

The other two things that this shows is the fact that logic in the child component, and actually what we see here is that child component is like a beautify string component, so all it does is that a string gets passed in from the parent, and what it'll do is attempt to beautify it for you.

But what'll happen is that logic to beautify the component will be executed multiple times redundantly, so that's something that of course is going to cause some unwanted overhead. And the third thing is the fact that... since the synchronization is two-way, that once the child component beautifies the string, it's going to pass it back into the parent component, and that may be an unwanted side effect.

So the first fix is to basically check for null values. If you're going to perform some method or operation on the instance variable in the child component after the synchronization occurs, you definitely want to check for null so you don't get runtime exceptions. Then to fix the other two issues, we want to do what's called disable synchronization. That's fairly simple to do. What you do is you overwrite a method in your child component. It's in white text there. It synchronizes variables with bindings and have that return false. That automatically tells the framework, the WebObjects framework, that your component's not to be synchronized automatically.

Once you go to manual synchronization, though, you need to perform the pushing and pulling of the attributes between the parent and the child yourself. I mean, that's where the value for binding method comes in. Okay, so in this case, you pass the value for binding method, the name of the attribute in the WAD file, in this case it's a string, and it will return the parent's bound attribute, and you can perform some operation on it.

Once you go to this manual synchronization and you start using the value for binding, you don't really need to have a declared instance variable in your child component anymore. So, something to think about. The other thing is you need a way to get values back into the parent sometime.

So in this case, you probably don't want to do it, but if you wanted to have that beautified string passed back into the parent, you'd use a set value for binding method. And that's how you manually push the values back from the child into the parent. Basically what you do is you just pass it the value and the name of the binding.

Another thing to consider is if you're going to pass into the child something like an EO or a dictionary and that child component is going to be doing operations on that object, whatever it is, maybe you're going to call, display all of its attributes. In the case we have here, maybe you're calling attributes on it 20 times to display name, address, city, state.

And in this example here, what would happen is you'd be calling value for binding multiple times, right? Once for every time the woe string fires off. Which probably isn't too expensive on its own, but if on the other side there's an accessor method with some kind of business logic, then that's going to start getting expensive.

So one thing you can do here is cache the value. Okay, so again, you can declare an instance variable, do a value for binding, check to see if it's null. If it's not null, you go ahead and load the value in and then cache it in the child component. If you're going to do that, of course, you want to remember to reset the value at the end of the current request response loop. Append to response is a good place to do that.

And then I thought I'd throw this in as well, we're on the subject of manual synchronization, is the idea of caret notation. If all you have are wrapper methods for value for binding and set value for binding, and all they're doing is calling those two methods, you can shorten this by using what's called caret notation. in the bindings in the child. Okay, so this saves you having to have these wrapper methods there and all the overhead those will incur.

[Transcript missing]

But there's also this kind of formalized notion of a stateless component in WebObjects where if you declare your component to be stateless, there will only be one shared instance of that component for all your user sessions. Or if you're running in a multi-threaded environment, there will be a pool of these components.

The benefit here, though, is that WebObjects at runtime doesn't have to keep creating new instances and garbage collecting these. It doesn't have to incur the overhead for doing that. So it becomes very efficient. So this is kind of like the best way to create the most efficient reusable component. It's important to note that you can have instance variables in these stateless components for doing local things, but the state is not guaranteed to be valid beyond the current phase of the request response loop.

So you want to consider that. So to make the component stateless, you basically implement a method called isStatelessReturnTrue, automatically your component stateless. You want to remember to implement a reset method and clear out or null out any instance variables you have in that component so you don't have any side effects in other sessions that are going to access that component.

And one thing I discovered as well is once you create a stateless component, it automatically uses manual synchronization. So if you just go ahead and make a component stateless that wasn't stateless before, you probably won't synchronize any of your bindings. You're going to have to do call value for binding, set value for binding. Another thing I learned as well is if you're going to use a stateless component, all the components, child components of that, need to be stateless as well.

Okay, so if we're going to get into stateless components or even stateful components sometimes, it's nice to have some flexibility to be able to communicate and share state outside the component. You might have multiple components that need to share some data and just basically be able to access data outside of the component itself and even the parent.

So one thing you might want to do is maybe the component needs to access the application, some data in the application, to configure itself. Just an idea. So you can, there's a convenience method on a component called application. You can call value for key, set value for key, or just call, do a cast and call some method on application.

You need to remember though, you might need a lock if you're running multi-threaded. Anytime you go outside your session in a multi-threaded app, you're probably not thread safe. So, kind of remember that. Another idea is if you have two components that need to share some kind of state, you can set up an instance variable in the parent and access it that way using the parent method in the component.

Yet another idea that I've seen used a lot is to use some shared state and session dictionary. When you do this, you kind of want to be careful to have some namespace considerations because it is a shared dictionary between all the pages and it's possible to get the wrong values back.

Another thing I've seen done that's kind of neat is the idea of this user info dictionary and the request object. The request object, once it comes in in the current request, is usually pretty much intact. Every single component has access to it, so you can kind of move information around through that user info dictionary and share information that way.

Kind of a more stealthy way of doing things. The way you'd access it is through the context, typically. Context, you can access the request, and then from the request you can get to the user info dictionary. Okay, with that, I'm going to ask Bob Frank to come up and give you some demos and talk about WoW component content, WoW switch component, and some of the cool dynamic features of reusable components.

Thank you, Kelly. I think I get to talk about what are probably two of the least understood reusable components that ship with WebObjects: WoSwitch component and WoComponent content. I also think I get to do the neatest demo of this presentation. WoSwitch component, hold on, let's see.

[Transcript missing]

The next component I'm going to be talking about, I think this is very hard to get your brain around. It's going to be a lot easier to see in the demo. Woe component content allows you to take a component and create a wrapper component.

So that way you could have a All of your components designed for their functionality and a set of wrapper components designed for their user interface. And I'm going to take Scott's application and wrap it with some user interface and you'll see that you can put them together. Using a combination of WoW Switch component and WoW component content, you could easily take a very small set of components that provide a look and feel for your entire site or a combination of sets of looks and feels for your entire site and on the fly, at run time, swap them in and out. What you see here on this screen is actually a very simple search field wrapped by a wrapper.

And that wrapper is going to actually provide the rest of the body for the page. And the search field is going to get dropped into the wrapper component, which looks like this. When you have a WoW component content, you can actually add a component to the page. So if you have a WoW component content, the content that you have wrapped gets dropped in and in Web Object Builder will be represented by a small little placeholder.

Since it doesn't know what you're wrapping and it doesn't know what it's going to look like, it just has this placeholder. In fact, let's see how that works. Can we go over to the demo machine? Let me clean up a few things. I have a few things that I have pre-built.

I love NT. We have a small framework with a few wrapper components that I have already built. In order to use it, I have to add my framework to the project. And since I'm adding a framework before we can go ahead and run, I'm going to have to recompile.

Just to show you that it's the same application, let me add a simple wrapper to the components that Kelly wrote. I'm going to center this so it looks better with mine. And add the Yaya wrapper. It may look familiar to you. Oh, and save. may look, the wrapper that we're using may look a little bit familiar. I hope.

[Transcript missing]

Let's say, for instance, you actually want to know how to do what I just did. If you have a variety of people working on Your user interface. And you want to go ahead and take their completed page and, well, gee, this looks like a really good. Why don't we go ahead and use a page here.

and say these are the very expensive graphic designers that we hired. And create a component and simply take a look at the HTML that is in the blank component. Don't care about any of it at all. Delete that and paste in the HTML that you've been provided. Don't forget to save. And When you're done, even with a complicated web page, WebObjectBuilder does a fairly good job at rendering it. And specifically, I'm going to go... Let's take a look at this table right here and insert my WoE component content.

[Transcript missing]

At this point, I need to drop in a few pieces of code. And don't worry, I'm not going to do anything magical behind the scenes, but I will show you the finished product first, and then go ahead and explain the few pieces that I have done.

[Transcript missing]

and I will be presenting the next session on the WOComponent content that allows us to switch between various wrappers that we have and go ahead and Use a pull-down, a woe switch right here, a woe pop-up list that Since I added some classes, we have to recompile.

But that is all that's involved in taking an HTML page, dropping in some component content, and making it into a wrapper. Hopefully, this will be nice to me this morning. The default page that comes up has no wrapper. Down at the bottom here, we have a variety of wrappers. The one piece of magic that isn't really that magical that I added is this class, dynamicwrapper.java.

And all it really does for the application is it looks for the name of the wrapper that I want to use. Using that action method that I had bound in that form, I was setting the name of the wrapper into the session, and we were pulling out here.

One nifty little piece of code that I added just last night was the ability to take the value from your URL. and this is just done using form value for key. Nothing very special at all. And that is the entire demo of how to combine WoW Switch Component and WoW Wrapper. Can I go back to the presentation?

One last thought on creating reusable components and reusable toolkits in general is there's a few pieces of code that you saw me copy and paste. There are a large amount of things that you can do for yourself to make reusable components even more reusable for yourself. One of the things that I like to do is have a copy, a personal copy of a subclass of WoW component that has a variety of convenience methods. Everybody has certain things that you're going to find yourself re-implementing time and time again.

You can carry this around with you, even subclassing an application or session, to provide convenience methods that you know will be available for you everywhere. For example, if you want to go through your application, a common example would be the ability to set certain pages to expire and set certain pages not to expire.

If you've got customer data that you don't want the browser to cache, you could set it on a page-by-page basis. There's a few other simple examples. Going back to the previous page, these are convenient things that over time I've found that are re-implemented frequently. This is a... At this point, I'd like to call back Kelly on stage and have him talk some more about additional reusable components.

Okay, I'm going to finish this up with some tips on performance and debugging and get into some ideas on some design ideas. Debugging. Of course we've got GDB if you're doing Objective-C, JDB if you're doing... If you are going to use Java, make sure you enable GDB and you also have to set other Java tool flags equal -g in your makefile.preamble if you want to be able to access local variables.

My favorite: System.out.println. Seems like half my code these days is System.out.println. There's also LogString, which is kind of a platform-independent way to do logging in web objects. And then there's DebugString that works in conjunction with WoDebugEnabled, so you can set this flag at runtime and turn your debugging on and off at will.

Another technique I use if I have deeply nested components or very complex components is to use comments to isolate different portions of the HTML. If I'm getting some kind of really weird browser output, sometimes it's nice to be able to go in and just comment out sections and kind of isolate where the problem is. Another thing that I found when I was researching this session is WoDebug.

It's basically a binding attribute that you can add to any component, whether it's a reusable component or a dynamic element. Essentially what you do is either in the WAD file or in the inspector, just add this attribute, set it to yes, and what it'll do for you is log on the console all of the synchronizations between the parent and the child. It's a very simple thing.

It's a very useful feature to have. You can see the WAD file down there. You can actually see the attribute on the child side, the attribute on the parent side. It actually shows you the values that it's pushing and pulling both ways. It's a very useful thing to have, to know about.

Performance Tips The first two things we already really covered: Disabled binding synchronization of stateless components. I wanted to put them on here just kind of check off things to think about when you're looking at performance issues. The other one that's kind of obvious is component definition caching. By default it's turned off.

So when you're in development mode, if you make changes to your WAD file or make changes to your component template, WebObjects will pick those changes up without you having to restart the application, which is kind of a nice feature. But when you go to deploy, you want to set "wo caching enabled" to "yes" on the command line, or set the method, which I think is an application method, to "true."

That'll make your application run a little bit faster. Although, once WebObjects determines that the component hasn't changed, it doesn't really go and reparse it every single time anyway. But it does check to see if the files changed on disk, so there is a little bit of overhead. Disable various debugging modes. You know, you want to make sure your console logging's off.

That really gets expensive. If you forget to turn that stuff off, you don't realize it's spewing all that stuff. We had a couple good sessions that went into performance on WebObjects, and I know they covered the WoEvent logging stuff. That's something to really consider using when you're evaluating performance of your components. I got an example of a URL for getting to the setup page. It's really intuitive to use. Maybe not so easy to interpret the results, but it is pretty nifty to have.

Pitfalls to avoid. These are things that I've run into and a lot of developers that I've worked with have run into several times. I thought I'd list here. The first one, take values from request isn't always invoked. So take values from request is only invoked if there are form values coming in in the request. So for example, the initial URL you submit to a WebObjects app that starts your session, there is no take values from request method invoked on your component. So if you put logic in there thinking that it's going to happen, you might want to think twice about that.

Initializing variables too early, especially if you're using automatic component synchronization. You might initialize a variable that's part of a binding attribute in maybe a constructor or something just to have it overwritten by the synchronization process. So it's best to kind of initialize your variables on a lazy basis. Initialize them when you need them.

Returning self or this from child components, pretty common mistake. Basically, nothing will crash when you do that, but what will happen is, for example, you'll all of a sudden just get your child component displayed in your browser and your main page is gone. That's pretty easy to fix. You typically want to return null or return some new page from an action method.

[Transcript missing]

Another thing, it's not too common, but you can get yourself into these retain cycles, which are essentially circular references between objects. For instance, if you try and store the session in a page, or you try and store the application in a page, what will happen is, since these objects are referencing each other, they might not get garbage collected at the end of whatever time it is to get rid of them.

At the end of the request response cycle or the end of the session, you'll start getting memory leaks. It's best not to do that. convenience methods and components for like application and session and parent, things like that, so you don't really need to store that kind of stuff in your components.

A few design issues to consider when building components. My favorite really is to take a building block approach. Start with really small components, build those into bigger components, and then build those into yet bigger components. I mean, it really is kind of a cool way to build UI and really reusable. And with the ability to create very efficient components with some of the things we talked about, you can really pull it off and do some kind of cool stuff. A couple questions to ask yourself when you design your component.

Is the component designed to be reused across applications? Not everybody is going to use reusable components in more than one application. If you are, you might want to consider having features in the reusable component to turn different things on and off to allow the programmer to control how it's going to behave. Decide how you want to manage state. You want to really think about that. Do you want to pass everything into the bindings or just do it?

I think you're right. You want to use some kind of shared state idea. Another thing to consider is binding validations. If other people are going to be using your reusable components, there is the API validation feature in WebObjects Builder. I wanted to point out that it's a design time only error check. So if you validate the rules on your component at runtime, you're not going to know the difference. I don't know if you've ever noticed, but on dynamic elements, if you don't do the bindings right or if you leave a binding out, you'll get a runtime exception.

You might want to provide that sort of error checking on your own in your own reusable components. There's a couple methods you can call: canGetValueForBinding, canSetValueForBinding. So, if it's required that the developer bind an attribute that the child can set back in the parent, you might want to make these, call these methods and then raise some kind of runtime exception if they don't return the right value. And then namespace conflicts. If you're creating frameworks of reusable components, you want to be, you know, give them some kind of unique names so they don't conflict with the components in your current application or in other frameworks. That's about it. That's what I've got. Q&A. Thanks.