MainScreen + Persistable in one BlackBerry class - model-view-controller

I have few classes for my Blackberry application right now. Now what I am doing is to create one screen for user to enter their information, store it inside the persistent storage, so that when they click Back on the navigation button, all the information they typed will be displayed on a list view.
My question is, I cannot create a class that extends MainScreen and implements Persistable at the same time because it will give me error.
How to solve this problem?
To make it easier for you guys to see, this is the fragment of the class that I have.
inMenu.add(new MenuItem ("Save",110,10)
{
public void run()
{
synchronized(uv.store)
{
Vector _data = (Vector) UserVector.store.getContents();
if (_data == null)
{
_data = new Vector();
UserVector.store.setContents(_data);
}
UserVector newRec = new UserVector();
newRec.setElement(UserVector.TITLE,titleLabel.getText());
newRec.setElement(UserVector.VENUE,venueLabel.getText());
newRec.setElement(UserVector.DESCRIPTION,descriptionLabel.getText());
_data.addElement(newRec);
UserVector.store.commit();
}
Dialog.inform("Information Saved!");
}
});

You are witnessing true proof of BlackBerry programming not being Java: the fact that an interface (Persistable) is not inherited.
In BlackBerry, if you want to persist a class, marking it as Persistable isn't enough. The entire class hierarchy upwards should be persistable. At the same time, marking a class Persistable would make you think that a subclass will inherit persistable, but it doesn't. You'll have to explicitly mark the subclass as Persistable. (I know, at this point you are probably thinking about this being an heresy, an atrocity, an ..., well, BlackBerry programming is full of tricky things like this). Think of Persistable as a marker interface which is not inherited.
In your case, you have a Runtime error telling you that in order to persist your screen, you'd have to make MainScreen implement Persistable, which of course you can't because you don't have access to the source code. Even if you could, there's another caveat: every field, collection, container in your screen should also be Persistable for the thing to work, otherwise you'd get an exception. So you are completely out of luck here because neither Field or its subclasses do implement Persistable.
But in any case, even if it were possible, it is not advisable to save an entire View (with its many nested objects) just for convenience. Instead, save the content of the fields and screen state in an small container object (implementing Persistable) and restore the screen when entering the app. This approach allows you to reuse your container object in case new Fields are added or removed from the GUI (otherwise you'd have to clean simulator memory each time you change the GUI design to avoid ClassCastException loading the screen from persistence). Because you are decoupling GUI from persistence, it also allows you to choose which fields are saved and which ones don't need to.

A MainScreen is a very complex class with many user interface elements in it. Even if you could persist an entire MainScreen I can't imagine why you would want to. The MVC pattern suggests that you keep the model (your persistent store) separate from your view and controllers.
It is probably easies to combine the view and controller in the MainScreen, but you can separate them out.
Another argument for not putting extraneous stuff in your persistent store, is every time you change it you have to either provide for migrating the old format storage to the new format, or force your users to re-enter the data again.

From the looks of it your UserVector class should implement Persistable and should have static methods for storing and retrieving a UserVector object from persistent memory.
Check out http://docs.blackberry.com/en/developers/deliverables/7693/Persistent_data_storage_509562_11.jsp for a good introduction to persistent storage.
Persistent memory is a bit like the Windows registry. You can lookup objects using a unique key, manipulate them, then save them back there as long as they are serializable (persistable). Do not try to save anything to do with your UI into persistent memory, only save data.
Also, if you are saving many user data, you might be better off looking at an SQLite database for storage.

Related

Is it bad to use ViewModelLocator to Grab other VM's for use in another Vm?

I am using MVVM light and figured out since that the ViewModelLocator can be used to grab any view model and thus I can use it to grab values.
I been doing something like this
public class ViewModel1
{
public ViewModel1()
{
var vm2 = new ViewModelLocator().ViewModel2;
string name = vm2.Name;
}
}
This way if I need to go between views I can easily get other values. I am not sure if this would be best practice though(it seems so convenient makes me wonder if it is bad practice lol) as I know there is some messenger class thing and not sue if that is the way I should be doing it.
Edit
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<ViewModel1>();
SimpleIoc.Default.Register<ViewModel2>();
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
"CA1822:MarkMembersAsStatic",
Justification = "This non-static member is needed for data binding purposes.")]
public ViewModel1 ViewModel1
{
get
{
return ServiceLocator.Current.GetInstance<ViewModel1 >();
}
}
Edit
Here is a scenario that I am trying to solve.
I have a view that you add price and store name to. When you click on the textbox for store name you are transferred to another view. This view has a textbox that you type the store you are looking for, as you type a select list get populated with all the possible matches and information about that store.
The user then chooses the store they want. They are transferred back to the view where they "add the price", now the store name is filled in also.
If they hit "add" button it takes the price, the store name, and the barcode(this came from the view BEFORE "add price view") and sends to a server.
So as you can see I need data from different views.
I'm trying to understand what your scenario is. In the MVVMlight forum, you added the following context to this question:
"I have some data that needs to be passed to multiple screens and possibly back again."
For passing data between VMs, I would also - as Matt above - use the Messenger class of MVVMLight as long as it is "fire and forget". But it is the "possibly back again" comment that sounds tricky.
I can imagine some scenarios where this can be needed. Eg. a wizard interface. In such a case I would model the data that the wizard is responsible for collecting and then bind all Views to the same VM, representing that model object.
But that's just one case.
So maybe if you could provide a little more context, I would be happy to try and help.
Yes, you can do this, in as much as the code will work but there is a big potential issue you may run into in the future.
One of the strong arguments for using the MVVM pattern is that it makes it easier to write code that can be easily tested.
With you're above code you can't test ViewModel1 without also having ViewModelLocator and ViewModel2. May be that's not too much of a bad thing in and of itself but you've set a precedent that this type of strong coupling of classes is acceptable. What happens, in the future, when you
From a testing perspective you would probably benefit from being able to inject your dependencies. This means passing, to the constructor--typically, the external objects of information you need.
This could mean you have a constructor like this:
public ViewModel1(string vm2Name)
{
string name = vm2Name;
}
that you call like this:
var vm1 = new ViewModel1(ViewModelLocator.ViewModel2.name);
There are few other issues you may want to consider also.
You're also creating a new ViewModelLocator to access one of it's properties. You probably already have an instance of the locator defined at the application level. You're creating more work for yourself (and the processor) if you're newing up additional, unnecessary instances.
Do you really need a complete instance of ViewModel2 if all you need is the name? Avoid creating and passing more than you need to.
Update
If you capture the store in the first view/vm then why not pass that (ID &/or Name) to the second VM from the second view? The second VM can then send that to the server with the data captured in the second view.
Another approach may be to just use one viewmodel for both views. This may make your whole problem go away.
If you have properties in 1 view or view model that need to be accessed by a second (or additional) views or view models, I'd recommend creating a new class to store these shared properties and then injecting this class into each view model (or accessing it via the locator). See my answer here... Two views - one ViewModel
Here is some sample code still using the SimpleIoc
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<IMyClass, MyClass>();
}
public IMyClass MyClassInstance
{
get{ return ServiceLocator.Current.GetInstance<IMyClass>();}
}
Here is a review of SimpleIOC - how to use MVVMLight SimpleIoc?
However, as I mentioned in my comments, I changed to use the Autofac container so that my supporting/shared classes could be injected into multiple view models. This way I did not need to instantiate the Locator to access the shared class. I believe this is a cleaner solution.
This is how I registered MyClass and ViewModels with the Autofac container-
var builder = new ContainerBuilder();
var myClass = new MyClass();
builder.RegisterInstance(myClass);
builder.RegisterType<ViewModel1>();
builder.RegisterType<ViewModel2>();
_container = builder.Build();
ServiceLocator.SetLocatorProvider(() => new AutofacServiceLocator(_container));
Then each ViewModel (ViewModel1, ViewModel2) that require an instance of MyClass just add that as a constructor parameter as I linked initially.
MyClass will implement PropertyChanged as necessary for its properties.
Ok, my shot at an answer for your original question first is: Yes, I think it is bad to access one VM from another VM, at least in the way it is done in the code example of this question. For the same reasons that Matt is getting at - maintainability and testability. By "newing up" another ViewModelLocator in this way you hardcode a dependency into your view model.
So one way to avoid that is to consider Dependency Injection. This will make your dependencies explicit while keeping things testable. Another option is to use the Messenger class of MVVMLight that you also mention.
In order to write maintainable and testable code in the context of MVVM, ViewModels should be as loosely coupled as possible. This is where the Messenger of MVVMLight can help. Here's a quote from Laurent on what Messenger class was intended for:
I use it where decoupled communication must take place. Typically I use it between VM and view, and between VM and VM. Strictly speaking you can use it in multiple places, but I always recommend people to be careful with it. It is a powerful tool, but because of the very loose coupling, it is easy to lose the overview on what you are doing. Use it where it makes sense, but don't replace all your events and commands with messages.
So, to answer the more specific scenario you mention, where one view pops up another "store selection" view and the latter must set the current store when returning back to the first view, this is one way to do it (the "Messenger way"):
1) On the first view, use EventToCommand from MVVMLight on the TextBox in the first view to bind the desired event (eg. GotFocus) to a command exposed by the view model. Could be eg. named OpenStoreSelectorCommand.
2) The OpenStoreSelectorCommand uses the Messenger to send a message, requesting that the Store Selector dialog should be opened. The StoreSelectorView (the pop-up view) subscribes to this message (registers with the Messenger for that type of message) and opens the dialog.
3) When the view closes with a new store selected, it uses the Messenger once again to publish a message that the current store has changed. The main view model subscribes to this message and can take whatever action it needs when it receives the message. Eg. update a CurrentStore property, which is bound to a field on the main view.
You may argue that this is a lot of messaging back and forth, but it keeps the view models and views decoupled and does not require a lot code.
That's one approach. That may be "old style" as Matt is hinting, but it will work, and is better than creating hard dependencies.
A service-based approach:
For a more service-based approach take a look at this recent MSDN Magazine article, written by the inventor of MVVMLight. It gives code examples of both approaches: The Messenger approach and a DialogService-based approach. It does not, however, go into details on how you get values back from a dialog window.
That issue is tackled, without relying on the Messenger, in this article. Note the IModalDialogService interface:
public interface IModalDialogService
{
void ShowDialog<TViewModel>(IModalWindow view, TViewModel viewModel, Action<TViewModel> onDialogClose);
void ShowDialog<TDialogViewModel>(IModalWindow view, TDialogViewModel viewModel);
}
The first overload has an Action delegate parameter that is attached as the event handler for the Close event of the dialog. The parameter TViewModel for the delegate is set as the DataContext of the dialog window. The end result is that the view model that caused the dialog to be shown initially, can access the view model of the (updated) dialog when the dialog closes.
I hope that helps you further!

Strongly typed ViewData for complex object persistence

I'm working on a ASP.NET MVC system where you may click on a ajax link that will open a window (kendo window but it does not affect the situation) which a complex flow. To make this less of a nightmare to manage, I made a ViewModel (as I should) but this ViewModel is a complex object due to the complexity of the procedure.
There is anywhere from a single to 5 windows that asks various questions depending on a lot of conditions (including, but not limited to, what time you click the link, who you are, what schedule is attached to your account and, obviously, your previous answers in this flow).
The problem is that having a complex object, I cannot simply make #Html.HiddenFor(o=>o.XXX). So I proceeded to find an alternative and it led me with a single option, TempData. I'm really not a fan of dynamics and object types. I'd really like to have this View Model strongly typed.
What would be the best way to approach this?
Here is a case where using Session or TempData might make sense. Contrary to popular belief, you can make these somewhat strongly-typed. Not like a viewmodel, but you can avoid keychain messes by using extension methods.
For example, instead of doing something like this:
TempData["NestedVariable1"] = someObject;
...
var someObject = TempData["NestedVariable1"] as CustomType;
You can write extension methods to store these variables, and encapsulate the keys and casting in the extension methods.
public static class ComplexFlowExtensions
{
private static string Nv1Key = "temp_data_key";
public static void NestedVariable1(this TempData tempData, CustomType value)
{
// write the value to temp data
tempData[Nv1Key] = value;
}
public static CustomType NestedVariable1(this TempData tempData)
{
// read the value from temp data
return tempData[Nv1Key] as CustomType;
}
}
You can then read / write these values from either controllers or views like this:
TempData.NestedVariable1(someObject);
...
var someObject = TempData.NestedVariable1();
You could use the same pattern with Session as well. And instead of saving each individual scalar value in a separate variable, you should be able to store an entire nested object graph in the variable. Either that, or serialize it to JSON and store that, then deserialize when you get it back out. Either way, I think this beats a ton of hidden fields written out to your view's form.

Entity Framework in detached mode with MVC application

I have started working out with Entity Framework (EF) for an MVC n-tier application. It would seem that very obvious that this being a web application (which is stateless), I would have to use detached object models. There is no ambiguity with doing an Add operation. However when doing an edit there are here are two ways
Fetch the original object in context, attach the updated object and
then save to database. Something like mentioned in answer to this
question
EF4 Context.ApplyCurrentValues does not update current values
Set individual modified properties explicitly using the IsModified property of individual fields of the object like
mentioned in this article
http://msdn.microsoft.com/en-us/data/jj592677.aspx
Method 1 has disadvantage of having to load object into memory from database each time an update needs to be performed.
Method 2 would require having to manually pass which fields to be set as IsModified to true from wherever the object an be updated. So for e.g. for each object, I may need to create a boolean collection object for each field of the object.
e.g.
SaveEntity(EntityClass e, EntityStateClass ec)
{
context.Entry(e).Property("Name").IsModified = ec.NameState;
context.SaveChanges();
}
class EntityStateClass{ public bool NameState;}
I would prefer method 2 simply for the sake of performance but I am hindered by the n-tier architecture and repository pattern I am using. My Repository interface restricts save method for any object to be
SaveEntity(EntityClass e);
So I cannot pass the "state" object. Context class is not available and should not be available outside DAL. So I cannot set property outside. Is there any "proper" way to achieve this ?
Note: Self-Tracking Entity is also out of question since I cannot send entities with state to client (the browser) since I am intent on keeping the html lightweight.
EDIT: After a lot of thinking, I am trying to use following mechanism to keep track of modified state for each field in my domain class
Declare a partial class for entity class.
For each field that is updateable, declare a boolean property like "IsModified_FieldName"
Set the "IsModified_FieldName" property when the field is set.
However for this I need Entity Framework to generate explicit properties for me instead of implicit properties that it auto-generates. Does EF provide an handle to do this ?
Here is sample code of what I am trying to achieve
//Save Method for class EntityClass.
SaveEntity(EntityClass e)
{
context.Entry(e).Property("Name").IsModified = e.IsModified_Name;
context.SaveChanges();
}
//EntityClass is class autogenerated by EF
public partial class EntityClass
{
//This is auto-generated property by EF
public string Name {get; set;}
/* This is what I would like EF to do
private string name;
public string Name
{
get {return Name;}
set {
name = value;
//this is what I would like to do
this.IsModified_Name = true;
};
}
*/
}
//This is another partial definition for EntityClass that I will provide
public partial class EntityClass
{
//This property will be set to true if "Name" is set
public bool IsModified_Name {get; set;}
}
PS: It seems the information I have provided is not sufficient and therefore there are no responses.
I am using DbContext (Database first model)
EF auto-generates the class files for me. So each time I update my database, the class files are regenerated.
To your concrete question: The entities are generated by a T4 template and it should be possible to modify this template (which is in text format) to generate the entities in a way you want to shape them.
But I have a few remarks about your concept:
In a web application data are usually changed by a user in a browser. To have a definite knowledge what really has been changed you need to track the changes in the browser (probably by some Javascript that sets flags in the data (a ViewModel for example) when a user edits a text box for instance).
If you don't track the changes in the browser what happens? The data get posted back to the server and you don't know at the server side (with MVC in a controller) which property has been changed. So, your only chance is to map all properties that has been posted back to your EntityClass and every property will be marked as Modified, no matter if the user really did a change or not. When you later call SaveChanges EF will write an UPDATE statement that involves all those properties and you have an unnecessary overhead that you you want to avoid.
So, what did you win by setting individual properties instead of setting the whole entity's state to Modified? In both cases you have marked all properties as Modified. Exceptions are partial changes of an entity, for example: You have a Customer entity that has a Name and City property and a view that only allows to edit the Name but not the City and a corresponding ViewModel that only contains a Name property. In this case your procedure would only mark the Name property of the Customer entity as Modified but not the City. You might save here a little bit because you don't save the City property value to the database. But you still save the Name even if it didn't change.
If you use solution 1 (ApplyCurrentValues) you have to load the entity first from the database, yes, but it would only mark the properties as Modified that really changed compared to their values in the database. If the user didn't change anything no UPDATE would be written at all.
Keep in mind that you are only at the beginning to implement your concept. There are other changes to the data that can happen in the browser than only scalar property changes, namely relationship changes. For example a user changes the relationship from an Order to a Customer or you have a view that has an Order and a collection of OrderItems and the user cannot only edit the Order header but also edit the OrderItems and remove and add new OrderItems. How do you want to recognize when the data come back from the browser to the server which collection item has been added and which has been removed - unless you track all those changes in the browser and send tracking information back to the server in addition to the actual data or unless you reload the Order and OrderItems from the database and merge the changes into the original entities from the database?
Personally I would vote for option 1 for these reasons:
You can use real POCOs that don't carry additional tracking information. (BTW: I have some doubt if you aren't reinventing the wheel by implementing your own tracking that EF change tracking proxies provide out of the box.)
You don't need to track changes in the browser which can become quite complex and will require Javascript in every Edit view to write change flags into hidden form fields or something.
You can use standard features of EF without having to implement your own tracking.
You are required to load entities from the database when you want to update an entity, that's true. But is this the real performance bottleneck in a web application where data have to run through the wire back and forth (and reflection (which isn't really known as to be fast) is involved by the model binder)? I have nothing said if your database is remote from the web server and connected by a 9600 baud modem. But otherwise, your plan is not only premature optimization, it is kind of premature architecture. You are starting to build a potentially complex architecture based on "it could be slow" to solve a performance problem that you actually don't know of whether it really exists.

Best practice for persisting database-stored lookup data at app level in MVC

Slogging through MVC+EF and trying to focus on doing things the right way. Right now I'm looking to add a dropdown to a form but I'd like to avoid hitting the database every time the page loads so I'd like to store the data in the app level. I figure creating an application level variable isn't the best approach. I've read about using the cache and static utility functions but surprisingly, nothing has sounded terribly definitive. (Static classes bad for unit testing, caching bad
So I have two scenarios that I'm curious about, I'm not sure if the approach would differ between the two.
1) A basic lookup, let's say the fifty states. Small, defined, will never change. Load at application startup. (Not looking for a hard coded solution but retrieval from the database.)
2) A lookup that will very rarely change and only via an admin-like screen. Let's say, cities/stores where your product is being sold. So data would be stored
in the model but would be relatively static unless someone made changes via the application. So not looking to hit the database every time I need to populate a dropdown/listbox.
Seems like basic stuff but it's basically the same as this topic that was never answered:
Is it good to use a static EF object context in an MVC application for better perf?
Any help is appreciated.
I will address you question in a few parts. First off, is it inherently bad to use static variables or caching patterns in MVC. The answer is simply no. As long as your architecture supports them it is OK. Just put your cache in the right place and design for testability as I will explain later.
The second part is what is the "right" way to have this type of persisted data stored so you don't have to make round trips to the DB to populate common UI items. For this, I don't recommend storing EF objects. I would create POCO objects (View models or similar) that you cache. So in the example of your 50 states you might have something like this:
public class State
{
public string Abbreviation { get; set; }
public string Name { get; set; }
}
Then you would do something like this to create your cached list:
List<State> states = Context.StateData.Select(s => new State { Abbreviation = s.Abbreviation, Name = s.Name}).ToList();
Finally, whatever your caching solution is, it should implement an interface so you can mock that caching method for testing.
To do this without running into circular references or using reflection, you will need at least 3 assemblies:
Your MVC application
A class library to define your POCO objects and interfaces
A class library do perform your data access and caching (this can obviously be split into 2 libraries if that makes it easier to maintain and/or test)
That way you could have something like this in your MVC code:
ICache myCache = CacheFactory.CreateCache();
List<State> states = myCache.ListStates();
// populate your view model with states
Where ICache and State are in one library and your actual implementation of ICache is in another.
This is what I do for my standard architecture: splitting POCO objects and interfacees which are data access agnostic into a separate library from data access which is the separate from my MVC app.
Look into using a Dependency Injection tool such as unity, ninject, structuremap, etc. These will allow for the application level control you are looking for by implementing a kernel which holds on to objects in a very similar way to what you seem to be describing.

How to construct two objects, with each other as a parameter/member

I have two classes that each need an instance of each other to function. Ordinarily if an object needs another object to run, I like to pass it in the constructor. But I can't do that in this case, because one object has to be instantiated before the other, and so therefore the second object does not exist to be passed to the first object's constructor.
I can resolve this by passing the first object to the second object's constructor, then calling a setter on the first object to pass the second object to it, but that seems a little clunky, and I'm wondering if there's a better way:
backend = new Backend();
panel = new Panel(backend);
backend.setPanel();
I've never put any study into MVC; I suppose I'm dealing with a model here (the Backend), and a view or a controller (the Panel). Any insights here I can gain from MVC?
It's time to take a look at MVC. :-) When you have a model-view-controller situation, the consensus is that the model shouldn't be aware of the view-controller (MVC often plays out as M-VC), but the view is invariably aware of the model.
If the model needs to tell the view something, it does so by notifying its listeners, of which it may have multiples. Your view should be one of them.
In a circular construction scenario I'd use a factory class/factory method. I would normally make the construction logic private to the factory (using friend construct, package level protection or similar), to en sure that no-one could construct instances without using the factory.
The use of setter/constructor is really a part of the contract between the two classes and the factory, so I'd just use whichever's convenient.
As has been pointed out, you really should try to find a non-circular solution.
First of all, contrary to what others has said here, there's no inherent problem with circular references. For example, an Order object would be expected to have a reference to the Customer object of the person who placed the Order. Similarly, it would be natural for the Customer object to have a list of Orders he has placed.
In a refernce-based language (like Java or C#) there's no problem, at all. In a value-based language (like C++), you have to take care in designing them.
That said, you design of:
backend = new Backend();
panel = new Panel(backend);
backend.setPanel(panel);
It pretty much the only way to do it.
It's better to avoid circular references. I would personally try to rethink my objects.
panel = new Panel(backend);
You do this in this routine something like
Public Sub Panel(ByVal BackEnd as BackEnd)
Me.MyBackEnd = BackEnd
BackEnd.MyPanel = Me
End Sub
You don't need BackEnd.SetPanel
It is better to use Proxies. A proxy links one object to another through raising a Event. The parent hands the child a proxy. When the child needs the parent it calls a GetRef method on the proxy. The proxy then raises a event which the parent uses to return itself to the proxy which then hands it to the child.
The use of the Event/Delegate mechanism avoids any circular reference problems.
So you have (assuming that the backend is the 'parent' here)
Public Sub Panel(ByVal BackEnd as BackEnd)
Me.MyBackEnd = BackEnd.Proxy
BackEnd.MyPanel = Me
End Sub
Public Property MyBackEnd() as BackEnd
Set (ByVal Value as BackEnd)
priBackEndProxy = BackEnd.Proxy
End Set
Get
Return priBackEndProxy.GetRef
End Get
End Property
Here is a fuller discussion on the problem of circular references. Although it is focused on fixing it in Visual Basic 6.0.
Dynamic Memory Allocation
Also another solution is aggregating Panel and BackEnd into another object. This is common if both elements are UI Controls and need to behave in a coordinated manner.
Finally as far as MVC goes I recommend using a a Model View Presenter approach instead.
Basically you have your Form Implement a IPanelForm interface. It registers itself with a class called Panel which does all the UI logic. BackEnd should have events that Panel can hook into for when the model changes. Panel handles the event and updates the form through the IPanelForm interface.
User clicks a button
The form passes to Panel that the user clicked a button
Panel handles the button and retrieves the data from the backend
Panel formats the data.
Panel uses IPanelForm Interface to show the data on the Form.
I've been delaying implementing the lessons learned here, giving me plenty of time to think about the exact right way to do it. As other people said, having a clear separation where the backend objects have listeners for when their properties change is definitely the way to go. Not only will it resolve the specific issue I was asking about in this question, it is going to make a lot of other bad design smells in this code look better. There are actually a lot of different Backend classes (going by the generic class names I used in my example), each with their own corresponding Panel class. And there's even a couple of places where some things can be moved around to separate other pairs of classes into Backend/Panel pairs following the same pattern and reducing a lot of passing junk around as parameters.
The rest of this answer is going to get language specific, as I am using Java.
I've not worried a whole lot about "JavaBeans," but I have found that following basic JavaBean conventions has been very helpful for me in the past: basically, using standard getters and setters for properties. Turns out there's a JavaBean convention I was unaware of which is really going to help here: bound properties. Bound properties are properties available through standard getters and setters which fire PropertyChangeEvents when they change. [I don't know for sure, but the JavaBeans standard may specify that all properties are supposed to be "bound properties." Not relevant to me, at this point. Be aware also that "standard" getters and setters can be very non-standard through the use of BeanInfo classes to define a JavaBean's exact interface, but I never use that, either.] (The main other JavaBean convention that I choose to follow or not as appropriate in each situation is a no-argument constructor; I'm already following it in this project because each of these Backend objects has to be serializable.)
I've found this blog entry, which was very helpful in cluing me into the bound properties/PropertyChangeEvents issue and helping me construct a plan for how I'm going to rework this code.
Right now all of my backend objects inherit from a common class called Model, which provides a couple of things every backend in this system needs including serialization support. I'm going to create an additional class JavaBean as a superclass of Model which will provide the PropertyChangeEvent support that I need, inherited by every Model. I'll update the setters in each Model to fire a PropertyChangeEvent when called. I may also have JavaBean inherited by a couple of classes which aren't technically Models in the same sense as these but which could also benefit from having other classes registered as listeners for them. The JavaBean class may not fully implement the JavaBean spec; as I've said, there are several details I don't care about. But it's good enough for this project. It sounds like I could get all this by inheriting from java.awt.Component, but these aren't components in any sense that I can justify, so I don't want to do that. (I also don't know what overhead it might entail.)
Once every Model is a JavaBean, complete with PropertyChangeEvent support, I'll do a lot of code cleanup: Models that are currently keeping references to Panels will be updated and the Panels will register themselves as listeners. So much cleaner! The Model won't have to know (and shouldn't have known in the first place) what methods the Panel should call on itself when the property updates.

Resources