tag:blogger.com,1999:blog-393540894130950585.post6985245745643170304..comments2024-03-22T00:23:29.865-07:00Comments on Never In Doubt: Screen FactoryWard Bellhttp://www.blogger.com/profile/10977457957771020146noreply@blogger.comBlogger17125tag:blogger.com,1999:blog-393540894130950585.post-24633024960477966412010-09-30T21:09:09.083-07:002010-09-30T21:09:09.083-07:00Thank you - this has solved a problem for me. I w...Thank you - this has solved a problem for me. I was having problems with view first or viewmodel first - neither seemed to always work for me in different parts of my app. View first worked initially when creating new data but got very messy when recreating the views from my database (I am using nested views to work on hierarchical data). I prefer to take a consistent approach and didn't want to use both.<br /><br />I like the name as well!Richard Gardinernoreply@blogger.comtag:blogger.com,1999:blog-393540894130950585.post-33627194436492199092010-04-09T20:33:09.884-07:002010-04-09T20:33:09.884-07:00Darius - Not ignoring you. Just buried right now a...Darius - Not ignoring you. Just buried right now and your thoughts require more than casual reflection. Hope to get back soon.Ward Bellhttps://www.blogger.com/profile/10977457957771020146noreply@blogger.comtag:blogger.com,1999:blog-393540894130950585.post-523657724179881212010-04-09T00:39:06.359-07:002010-04-09T00:39:06.359-07:00Another approach to this is also playing on my min...Another approach to this is also playing on my mind. The parent presenter could instead be a View Model that contains a view model property for each child view. The datacontext of the parent view would then be bound to its viewmodel and as the contained child views inherit this context, they would set their datacontext to the inherited datacontext.childviewmodel - where childviewmodel is the viewmodel for that particular view. Any composite actions are still maintained in the parent view model. Thoughts?Unknownhttps://www.blogger.com/profile/07698264443679759480noreply@blogger.comtag:blogger.com,1999:blog-393540894130950585.post-19394229061425551902010-04-09T00:30:54.541-07:002010-04-09T00:30:54.541-07:00Ward, having read both your articles and all the c...Ward, having read both your articles and all the comments for both - it seems clear to me that what you are talking about here is a composite view. The way I have created this in the past is to create a view (let's call it the parent view) that contains a grid, itself containing several ContentControls that have a region attached. The 'child' views are loaded up into the content control 'regions' via view discovery (i.e. wired up in the module class) when the parent view is displayed itself (either by view discovery or view in injection, take your pick). The parent view has a presenter, not a view model since there is no actual model bound to the parent view. The parent view's presenter handles any composite logic. In this way we don't need to introduce any additional class types.Unknownhttps://www.blogger.com/profile/07698264443679759480noreply@blogger.comtag:blogger.com,1999:blog-393540894130950585.post-30099024744208103662009-09-27T11:22:27.306-07:002009-09-27T11:22:27.306-07:00Ward,
I agree with Glenn in that it makes sense t...Ward,<br /><br />I agree with Glenn in that it makes sense to have a CompositeView that coordinates sub-views via its CompositeViewModel.<br /><br />It also eliminates potential confusion between the scope of Screen and Shell, and in the case where a PRISM IRegionManager is being used, still conforms to the convention of adding a "View" to a region (as opposed to a screen).<br /><br />Thoughts?Ryan Haneynoreply@blogger.comtag:blogger.com,1999:blog-393540894130950585.post-30016192304762797692009-08-26T08:10:00.872-07:002009-08-26T08:10:00.872-07:00Hi, I've just come to the party late and I'...Hi, I've just come to the party late and I'm sort of new to the whole presentation patterns stuff but may I suggest instead of Screen Conductor, Screen Factory, etc, how about Layout Conductor, Layout Factory etc. A layout doesn't convey a large area such as a screen but can be small enough to be part of a tab or composite item on a larger layout. What do you think? Anyway wanted to thank you and your other collaborators in enlightening me in designing better GUI frameworks and apps. <br /><br />Regards, ColinColinhttps://www.blogger.com/profile/01962000164959532235noreply@blogger.comtag:blogger.com,1999:blog-393540894130950585.post-7383012967347893742009-07-19T11:10:42.499-07:002009-07-19T11:10:42.499-07:00Hi Ward, As someone who is just starting to use MV...Hi Ward, As someone who is just starting to use MVVM for the first time, I'm finding your blog very interesting and helpful. I have a couple thoughts on your nomenclature conundrum. A factory should be named after what it produces. In the case where you have a single view composed of one or more MVVM triads, I agree with you that a "View" (in the MVVM sense of "View") isn't what is being built. I also agree that "ScreenFactory" isn't quite right because a "screen" feels like the entire application window, not simply a meaningful section of this window. So, please allow me to propose a few alternative...maybe one of them will resonate with you: ViewSetFactory, ViewGroupFactory, ViewCoordinatorFactory (ha!), UIModuleFactory, FrameFactory, UIFrameFactory, AppletFactory. I had a number of other ideas but these were my favorites. I think I like AppletFactory the best. I guess it's sort of a Java term, which may offend some people around these parts, but that seems to be the only single word that really brings home the idea of "a coordinated set of MVVM triads that form a meaningful unit of the overall UI". EDIT: I guess AppletFactory wasn't sitting with me as well I thought it was, but I came up with something similar but maybe more apt: ScreenletFactory.DanMhttps://www.blogger.com/profile/15201510131048041451noreply@blogger.comtag:blogger.com,1999:blog-393540894130950585.post-18943763015158458782009-07-19T09:51:44.916-07:002009-07-19T09:51:44.916-07:00This comment has been removed by the author.DanMhttps://www.blogger.com/profile/15201510131048041451noreply@blogger.comtag:blogger.com,1999:blog-393540894130950585.post-6315216472215934742009-07-08T02:18:44.071-07:002009-07-08T02:18:44.071-07:00@Ward
I see what you mean now in saying that scre...@Ward<br /><br />I see what you mean now in saying that screen is introduced as a higher level concept. <br /><br />Still and all it feels like a Composite View. You describe Order Entry, and Payroll, I see these as Composite Views which perhaps may have a SupervisingController / or higher level VM that strings them together. <br /><br />For example, in the Prism StockTraderRI we had a CompositeView representing a buy/sell transaction. Whether or not the "Screen" can close would be the job of that controller. Now maybe what i am thinking of as a controller is what you are calling Screen.<br /><br />GlennGlenn Blockhttp://blogs.msdn.com/gblocknoreply@blogger.comtag:blogger.com,1999:blog-393540894130950585.post-63321129411855061122009-07-02T15:11:42.395-07:002009-07-02T15:11:42.395-07:00Mikael - I agree that a screen often holds its own...Mikael - I agree that a screen often holds its own unit-of-work. <br /><br />When I edit Customer Acme and Customer Zeta simultaneously, changes to Acme are independent of changes to Zeta and their respective persistent object graphs should be kept apart.<br /><br />Within a screen, which represents a sizeable user scenario, it is usually sufficient to have a single unit-of-work.<br /><br />As in all things, one may depart from this advice and share units-of-work across screens or require multiple uow within a screen. Such departures are exceptionally rare in my experience.Ward Bellhttps://www.blogger.com/profile/10977457957771020146noreply@blogger.comtag:blogger.com,1999:blog-393540894130950585.post-82996192287026520412009-07-02T15:04:50.357-07:002009-07-02T15:04:50.357-07:00Glenn - I'm going to have to disagree. A Scree...Glenn - I'm going to have to disagree. A Screen is not a View. <br /><br />A screen represents the UI of a large-scale user scenario (e.g., CustomerEditor) which visually occupies some defined display space managed by a ScreenConductor.<br /><br />A Screen HAS a view ... perhaps a mini-shell ... which the ScreenConductor may place on the physical display ... but it is more than just that view. It is a higher level concept that responds to demands from the ScreenConductor that are particular to screens alone. As such, it is not eligible for Composite Pattern treatment.<br /><br />Let's look at a candidate IScreen. Its members include View, yes, but also (probably) ScreenSubject, CanClose, Close, Activate, and Deactivate.<br /><br />At first blush we say "views can close", etc. But upon closer inspection we realize that we mean something else. <br /><br />Most obviously, View's don't have to have a subject. A tabular view, for example, has no one subject. <br /><br />A view (and here I mean a View's ViewModel) need not know whether it can close or how to close. It likely contains information relevant to closing ... but, as a participant in a nexus of companion views that collectively implement the screen, no one of the views can speak for all.<br /><br />The Screen speaks for all of it's composite views. At least the Screen is responsible for all, even if, in practice, it delegates some or all of the responsibility to its ViewModel(s).<br /><br />You could require all of your views to implement IScreen and supply them with do-nothing implementations; but that does violence to the Composite pattern.<br /><br />Moreover, the Composite pattern exists to support iteration over a graph of heterogenous objects with a common base type.<br /><br />There is no such graph of screens. The ScreenConductor maintains a flat collection of screens that have no relation to each other. Nor do we want anything to be probing into the interior of a screen to probe for (possibly) nested views.<br /><br />It may be possible to construct a screen without benefit of a ScreenFactory. In practice, I find this so fraught with complexity and murkiness that I would always avoid it. I can't speak for Jeremy but I believe he said he shares my opinion on this.<br /><br />Of course there will be some screens that are so incredibly simple that they are little more than wrappers around a view. If this were often the case, we'd never have brought this up.<br /><br />We're after bigger fish. We're trying to understand how to manage complex screens such as CustomerEditor, OrderEntry, and PayrollTimesheet. These fellas are typically rich in various UI controls, hold lots of pending state changes, and lend themselves to compositional implementations.<br /><br />Suppose we've made a change to the Address view within a CustomerEditor. Who knows if the CustomerEditor can close? The Address view? I don't think so.<br /><br />The Address view's VM knows that an address change is pending but that VM cannot determine whether the change can be discarded in this scenario.<br /><br />The address view is deep inside the CustomerEditor. There is no obvious way for the ScreenConductor to know of its existence let alone ask the address view if it can be closed.<br /><br />You might conjure up some event-driven scheme where each view heard about a close request and recognized the request as pertinent (good luck). Then what does it do? Vote? Who counts the votes? Is one view's vote more important than another view's vote?<br /><br />It just gets ridiculous if you bubble this complexity up to the level of the application as a whole (or to the ScreenConductor). However such decisions are made, they are made within the boundary defined by the screen.<br /><br />We need a distinct construct to represent the screen as an integral whole, as a thing unto itself. <br /><br />The ScreenConductor wants one point of contact when it asks "Can You Close?". There is one locus for decision making ... the Screen.Ward Bellhttps://www.blogger.com/profile/10977457957771020146noreply@blogger.comtag:blogger.com,1999:blog-393540894130950585.post-91917067858719294242009-06-29T17:54:14.690-07:002009-06-29T17:54:14.690-07:00Nice Post Ward.
I prefer View Factory as well. In...Nice Post Ward.<br /><br />I prefer View Factory as well. In a composite application, a "screen" can be a mini-shell with it's own screens embeddeed within. In that sense I think they are all just views. Also if you look at the GOF Composite pattern, the premise is that each node can be treated as the whole.<br /><br />In many instances today, the "screen factory" is actually something offloaded to the IoC container of choice alongwith some configuration magic.Glenn Blockhttp://blogs.msdn.com/gblocknoreply@blogger.comtag:blogger.com,1999:blog-393540894130950585.post-89784880718224504482009-06-25T09:04:56.045-07:002009-06-25T09:04:56.045-07:00Thank you for an interesting post. It was very tim...Thank you for an interesting post. It was very timely because I was battling with the same naming issue just couple weeks back. I ended up calling your "Screen factory" as a "Screen composer" and your "Director" as a "Controller".<br /><br />In my application (WPF client built around the Prism) only one module can be active at all times. User can switch between the modules by clicking the appropriate icon and when that happens the old module is closed and the new module is shown. Inside the module there can be multiple screens. Every screen represents one tab page. When a screen is activated, it's up to the Screen Composer to build the screen. It creates the required presenters (I'm using MVP), hooks them up with the same Screen Controller and then asks the presenters to show the view. Presenters don't communicate directly with each other, instead they talk to the screen controller.<br /><br />There's one other thing which my screen composer currently handles: Hooking the screen components with the same unit of work. I want one unit of work per screen and I want the screen controller to take care of the unit of work. Currently the uow is created by the screen composer which makes the class a little too complex. But it shouldn't be hard to transfer that part of the code outside of my composer.<br /><br />-MikaelMikael Koskinenhttps://www.blogger.com/profile/12255714697806010275noreply@blogger.comtag:blogger.com,1999:blog-393540894130950585.post-25422434034762145662009-06-16T21:00:22.551-07:002009-06-16T21:00:22.551-07:00@Julian ... thanks for the thumbs up.
I remain co...@Julian ... thanks for the thumbs up.<br /><br />I remain conflicted on the name but I'm still favoring "ScreenFactory".<br /><br />I was re-reading my post to see if I still felt that way and realized that I hadn't been as clear as I wanted to be about when you really need a Coordinator or a Factory.<br /><br />I was trying to describe the construction and management of a complex Composite View. Such a view consists of a structure of NESTED sub-views.<br /><br />In a Composite View there is typically an uber-view class that acts as a kind of shell into which we drop the sub-views.<br /><br />Many times you can create this uber-view and the sub-views, put them all in their proper slots, and you're done.<br /><br />But just as often you will find that the sub-views have to communication and you want a single point of contact ... a mediator ... to manage the conversation ... and to communicate outside the Composite View.<br /><br />The Composite View is not simply a visual boundary. It also establishes an operational boundary within which the sub-views interact. They are invisible to code outside the Composite View.<br /><br />Considered from the outside, this Composite View is a "Screen". A Screen Conductor might find one of these in its Screen Collection. And it would call upon a ScreenFactory or Coordinator to make a new one.<br /><br />The Screen Conductor would never make the sub-views; it has no idea they even exist. Only the ScreenFactory (or Coordinator) would know to create the sub-views.<br /><br />Meanwhile, the ScreenFactory ... in the process of constructing the sub-views (each an MVVM triad) might resort to View Factories to acquire the sub-view "V"s.<br /><br />It is this vision, dancing in my brain, that leads me to distinguish ScreenFactory from ViewFactory and to prefer the term "ScreenFactory" when describing the "big view" dynamics that were the subject of my post.<br /><br />But choose what works for you. I'm sure not going to start a war over whether you open a soft-boiled egg from the big end or the small end.Ward Bellhttps://www.blogger.com/profile/10977457957771020146noreply@blogger.comtag:blogger.com,1999:blog-393540894130950585.post-41720922021020419662009-06-16T20:31:13.856-07:002009-06-16T20:31:13.856-07:00@Rob. Yes, ... I think we're aligned now. I re...@Rob. Yes, ... I think we're aligned now. I recall you made a comment about how GoF had something to say on this after I had said I hadn't remembered GoF contributing on it. <br /><br />Well GoF didn't tackle Separated Presentation patterns as we describe them now. But you are right, they WERE talking about UI scenarios.<br /><br />The Mediator example might have been an MVC discussion. Back in the day, the "V"s were the individual controls in the dialog. Today the "V"s we talk about are entire structured collections of controls. Progress I guess.<br /><br />BTW, John Papa and I have been kicking around the Screen Conductor off-and-on all day. Something is bound to come of it.Ward Bellhttps://www.blogger.com/profile/10977457957771020146noreply@blogger.comtag:blogger.com,1999:blog-393540894130950585.post-83429672314232474172009-06-16T06:03:04.574-07:002009-06-16T06:03:04.574-07:00Great post! I like these names better also, precis...Great post! I like these names better also, precisely for the arguments you exposed: it mainly manages creation of the MVVM triads, and the wireup between them althouth it's after the CLR instantiated the classes, is still part of the creation process.<br />By the way, I prefer the "View Factory" name better, because even it might get confused with the "V" in mVvm, it's the "View" in these acronyms the objective of the creation. You wouldn't think of creating a VM in the first place if there was not any View to display it. When the Controller is creating the MVVM triad (or a pure View-with-code-behind-and-no-separated-model), all that it cares is asking the "view factory" for a view, and it will be this class who would be the main consumer of the factory by calling ViewFactory.GiveMeTheViewByBuildingItUpAsYouWish().Julian Dominguezhttp://blogs.southworks.net/jdomingueznoreply@blogger.comtag:blogger.com,1999:blog-393540894130950585.post-26894956939305492672009-06-15T16:32:11.639-07:002009-06-15T16:32:11.639-07:00Ward, once again, really insightful post! I think...Ward, once again, really insightful post! I think I am seeing eye to eye with you now. When you were previously discussing the "Coordinator" I was thinking much more in terms of activation/deactivation. Mainly, because that is what I associate with the word. I have been thinking about our excahnge on your blog, trying to understand your scenario and pondering whether it was better to repurpose an old term (Supervising Controller) or invent a new term (Director). In other words, which would be most expressive and introduce minimal confusion into our pattern language. I really like your choice of "Screen Factory." It leverages the GoF Factory without changing its meaning, but specializes it by applying the "Screen" modifier. What's interesting about GoF is that a lot of those patterns, if you remember the original narrative section, were related to solving UI problems. One of the things I am going to blogging about is how various GoF patterns manifest themselves in the presentation layer, specifically as part of a VM.Anonymousnoreply@blogger.com