420 likes | 433 Views
GUI Architectures. GUI and systems Presentation and models Views and presentation logic. GUI Architectures. GUI and systems Presentation and models Views and presentation logic. Visual Interfaces and Application Logic. Yes, with a widget-based system
E N D
GUI Architectures GUI and systems Presentation and models Views and presentation logic
GUI Architectures • GUI and systems • Presentation and models • Views and presentation logic
Visual Interfaces and Application Logic • Yes, • with a widget-based system • it is easy to avoid having to think about the (required) separation • between the user interface • and the application domain objects, • but it is all too easy to allow • one’s domain code • to become inextricably linked with • the general interface logic. • From Dolphin Smalltalk design report [TWISTING THE TRIAD] Design paper for Dolphin Smalltalk, 2000
How to Select an Application Architecture Caching?State? Users Focus UI Components 1 Presentation Layer UI Process Components 2 ”Interface logic” ”Domain code” Communication Operational Management Security Service Interfaces Business ServicesLayer Business Workflows Business Components Business Entities Data Access Logic Components Service Agents Additional Services Layer Data Layer Data Sources Services [MSF], Microsoft Solution Framework, [MSPnP] patterns & practices: Architecture
Integrated Logic • Let us make a quick booking solution WizardForm with a BookingForms • Using the Visual Studio Design Wizard • Including direct access to the database • Generated code for saving a new booking private void bookingBindingNavigatorSaveItem_Click(object sender, EventArgs e) { this.Validate(); this.bookingBindingSource.EndEdit(); this.tableAdapterManager.UpdateAll(this.rBSDataSet); }
The Elements of the Integrated Program Visual Studio creates a binding source-object Acts as a data source for navigation bar and data grid level of indirection with a uniform protocol May be bound to different kinds of data sources Is an adapter between the data clients and the data source The binding source gets its data from the dataset An off-line representation of part of the database A table adapter synchronizes the dataset with the database Fills the dataset and updates the database Small group discussion Identify the layers of this solution on the reengineered structure at the next slide With permission from ProgramUtvikling as
Reengineering the Integrated Program :Program :RoomsForm «launch» roomsBindingNavigator : BindingNavigator -event handler roomsDataGridView : DataGridView +BindingSource +DataSource :BindingSource -roomsBindingSource -roomsTableAdapter +DataSource -rBSDataSet :RoomsTableAdapter :RBSDataSet «use» «use» «table» :Rooms
Study the Application Logic Identify the responsibilities of each layer The presentation layer Knows how to present, receive and navigate through data The data source layer Knows how to make data available to the presentation layer Keeps track of which data have been removed, added or changed Knows how to move data between the data source and the off-line data representation There is no domain logic in this application Information about the rules for using the data It is with the user alone
Add some Domain Logic Add data validation Entered number of seats cannot be negative Class Discussion: Evaluate alternative strategies Add constraint to the database CK_SeatsNonNegative: ([Seats]>=(0)) Discussion: Add constraint to the dataset Discussion: Add validation code run during data input Event handling for cell value changed Discussion:
Some Possible Considerations Add constraint to the database Can not be validated before data is saved Signalled by throwing an exception Must be caught and handled in the application Add constraint or validation to the record set Unique constraints and foreign-key constraints are readily available OnColumnChanging event handler may add further validation Requires manual programming Record set will have domain validation Add validation code run during data input Makes immediate validation possible Data grid will have domain validation Requires manual programming Where to locate that code?
Rudimentary Data Validation for Number of Seats Event handling for cell value change Located in RoomsForm private void roomsDataGridView_CellValueChanged( object sender, DataGridViewCellEventArgs e) { DataGridView senderView = (DataGridView)sender; if (e.RowIndex >= 0) // Only validate data cells { switch (senderView.Columns[e.ColumnIndex].HeaderText) { case "Seats": ValidateSeats(senderView, e.RowIndex, e.ColumnIndex); break; } // switch HeaderText } // rowIndex >= 0 }
A Support Function to do the Validation /// <summary> /// Validate data entry for the Seats property /// <pre>Pre: The current cell is a Seats data cell</pre> /// <post>Post: If the current value is valid, nothing has happened, else /// the user has been notified and the cell has been restored to its /// previous value</post> /// </summary> private void ValidateSeats(DataGridView sender, int row, int column) { object valueObject = sender.Rows[row].Cells[column].Value; if (valueObject != null && valueObject.GetType() != typeof(System.DBNull)) { int value = (int)valueObject; if (!(value >= 0)) { MessageBox.Show("Invalid value: " + value); sender.Rows[row].Cells[column].Value = currentValue; } } // has a value } // ValidateSeats
Architecture and Dependencies Presentation Layer Input Controller View MessageBox SaveItem_Click Binding Navigator CellEnter Data Grid View CellValueChanged Rooms Form Load Binding Source FormClosing Domain Layer Model ValidateDirty Dirty Validate Seats Save Data Source Layer Data Source Logic TableAdapter Record Set
Architecture and Dependencies Presentation Layer Input Controller View MessageBox SaveItem_Click Binding Navigator CellEnter Data Grid View CellValueChanged Rooms Form Load Binding Source FormClosing Domain Layer Model ValidateDirty Dirty Validate Seats Save Data Source Layer Data Source Logic TableAdapter Record Set
GUI Architectures • GUI and systems • Presentation and models • Views and presentation logic
Transaction Script Integrates All Logic Searchand display Modify,save, display Presentation andpresentation Logic Application Logic
A Solution with an Object Model • Example code to insert a booking private void AddButton_Click(object sender, EventArgs e) { Booking candidate = MakeNewBooking(); if (BookingValidation.IsValid(candidate)) { Mapper.BookingMapper.Add(candidate); LoadData(); LocateAt(candidate); } else { MessageBox.Show("Illegal booking data entered"); } }
Presentation is Supported by Domain • Run application and make a booking • Input event is caught by an event handler • Does some validation • Supported by domain objects • Calls domain objects to do some operation • Displays result • Similar to a pure update (next slide) • Design principle: Separate Presentation • Information flow: Flow Synchronization • The form knows who needs the information
Query Example: Get Available Rooms For queries / accessors (no change) or one single view Transfer result to View Logics From time: 2006-12-12 Fossekallen 2006-12-12 10.00–12.00 Setesdal 2006-12-12 10.00–15.00 Fossekallen 2006-12-12 14.00–17.00 To time: 2006-12-12 Search 5 display list 1: click event 2: get data 4 DisplayAvailable(rooms) : Input Controller : View or Presenter Presentation logic Domain logic 3 rooms = GetAvailable(from, to) = model in MVC terms : BookingFinder
A More Elaborate Example • Run application with several windows displaying overlapping information • You want a change in one of the windows to appear in the others • Design principle: Separate Presentation • Information flow: Observer Synchronization • Design pattern: Observer • .NET implementation: Events • Implicitly handled by data binding
Command Example: Reserve a Room For commands / transformers (change) and more than one view View subscribes to Service Layer events Notification is implicit through events (Separate Presentation) Fossekallen Fossekallen 2006-12-12 10.00–12.00 Setesdal 2006-12-12 10.00–15.00 Fossekallen 2006-12-12 14.00–17.00 Room: 2006-12-12 08.00 From time: Controls To time: 2006-12-12 12.00 Reserve 6 display list 1: click event 2: get data : Input Controller : View Logic Form class 4 change event 5 get display info 3 ReserveRoom(room, from, to) Presentation layer = model in MVC terms Domain layer : Booking
Subscribing To and Handling Events Observer Subscribes to (or is subscribed to) the event and does initial update Receives events to handle incremental update 1 2
Implementing Observers in C# Part 1: Initialization – Define and subscribe to the event Model (class Booking) declares an event public event System.EventHandler ParticipantsChanged; Observer client supplies a model to the observer RBS: new BookingForm(booking).Show(); BookingForm: new AddParticipantForm(booking).Show(); Observers define event handler for incremental event handling BookingForm, AddParticipantsForm private void booking_ParticipantsChanged(object source, System.EventArgs args) {...} Observers subscribe to the event (in constructor or set Model property) booking.ParticipantsChanged += new EventHandler(booking_ParticipantsChanged); Observers perform initial update from model Part 2: Update – Model triggers and observer receives event Model (class Booking) fires event (e.g. in AddParticipants) ParticipantsChanged(this, new System.EventArgs()); Causes observer (BookingForm, AddParticipantsForm) event handler to be called booking_ParticipantsChanged(object source, System.EventArgs args);
Adding Another UI Device • You want to allow room booking over the web • Display a simple demo of ASP.NET server side application logic • A data grid bound to Booking objects • Through BookingMapper • Don’t forget to initialize the MapperFactory singleton • Four separate fields and a button implement booking functionality • Web application is supported by same domain logic as before • Thanks to Separate Presentation
A Web Session server client
One Page Life Cycle server client
Handling ASP.NET Page Life Cycle Events A page raises events for each stage of its life cycle Can be handled in your own code Bind the event handler to the event Declaratively using attributes such as onclick In code Pages also support auto event wire-up ASP.NET looks for methods with particular names Automatically runs those methods when certain events are raised Requires <%@ Page AutoEventWireup="true" %> Naming convention Page_event Page_Load, Page_Init
Web Servers are Stateless The HTTP protocol does not relate subsequent Web requests to each other The request following mine may come from a completely unrelated browser The server must establish the connection between related requests By storing an identification at the client side This identifies a session from one browser Two main strategies for recognizing a session identity Server stores an id with the client and asks for it each time Cookies Server includes an id in the Web page, returned with the next request Hidden field A parameter in the URL
Strategies for Storing Session State Once the session is identified The session state data may be retrieved Different data storage techniques Session State Session identifier identifies a state object in server memory Contains all the session variables View State Session data sent between server and client with each view Persistent State Session variables stored on disk Search key = session identifier
Working with Session Data ASP.NET Session data object is only accessible through a Web page Encapsulate session data in a typed class Declared separately internal class TypedSession {private HttpSessionState session;public TypedSession() {session = System.Web.HttpContext.Current.Session;}public string UserId{ get { return (string)session[”UserId”]; } set { session[”UserId”] = value; }} ... more session variables ... } Used from a Web page or layer supertype object, initialised in Page_Load private TypedSession Session = new TypedSession(); Reference to System.Web.dll required
Delegate Event Handling to Input Controller Getting hold of an input controller Suggest an implementation of the Controller property
Getting Hold of a Controller One implementation of the Controller property In the code-behind class Implement the controller as a local ”singleton” The controller may have to call back for properties or commands private MyInputController controller; protected MyInputController Controller {get { if (controller == null){ controller = new MyInputController(this); } return controller;} }
Initial Page-Load Event Handling Initial loading of a page is done signalled in Page_Load event handler if (!IsPostback){Controller.HandleRequestParameters(parameters);this.LoadFormData(); }
GUI Architectures • GUI and systems • Presentation and models • Views and presentation logic
Validation code • From WinForm solution Booking candidate = MakeBooking(); if (BookingValidation.IsValid(candidate)) { Mapper.BookingMapper.Add(candidate); LoadData(); LocateAt(candidate); } else { MessageBox.Show("Illegal booking data entered"); }
Validation Code • From WebForm solution Booking candidate = MakeNewBooking(); if (IsBookingValid(candidate)) { Add(candidate); Response.Redirect("BookingsForm.aspx"); } else { Response.Write("<P>Den nya beställningen är inte giltig</P>"); }
The Input Handling is The Same • There is code duplication between the two • Symptom of wrong location • Separate common code in a separate input controller class • Delegate from event handler to input controller • Supply the information needed by the controller • Some of the functions may be pushed all the way to the domain logic • Similar situations occur on output • Separate out common presentation aspects in a presenter • Presenter must talk with the form • The form is dumb • Input controller and presenter may be developed using TDD • May be combined into one Input Controller/Presenter
Communication Scenario for MVC 7: if (alarm) SetColor(red) 6: alarm = IsAlarm 5: ShowBookings 4: GetBookings 3: BookingAddedEvent 2: AddBooking 1: NewBooking : Form 5 , 7 1 : Input Controller : Presenter 3 2 , 6 4 : Domain Logic = model in MVC terms
Issues for Different Output Devices • The controller and presenter do the same job for both windows and web • Talk to the form through an interface • Or use an adapter in-between • Requires all output operations in the form to be formalised • SetBookingList(bookings) • instead of BookingDataGrid.DataSource = bookings • Defined in the interface • Implemented in each of the forms or the adapter • The forms may be replaced by dummy classes for testing • The whole application is tested except physical input and display
Exercise 6.2 – Web Presentation Architecture : Page 7: if (alarm) SetColor(red) 6: alarm = IsAlarm 5: ShowBookings 4: GetBookings 3: BookingAddedEvent 2: AddBooking 1: NewBooking or : Form 1 5 , 7 : Input Controller : Presenter 3 2 , 6 4 : Domain Logic
References [TWISTING THE TRIAD] Andy Bower, Blair McGlashan, TWISTING THE TRIAD, The evolution of the Dolphin Smalltalk MVP application framework, Tutorial Paper for ESUG 2000, http://www.object-arts.com/papers/TwistingTheTriad.PDF