• Español – América Latina
  • Português – Brasil
  • Tiếng Việt
  • Android Developers

The role of the UI is to display the application data on the screen and also to serve as the primary point of user interaction. Whenever the data changes, either due to user interaction (like pressing a button) or external input (like a network response), the UI should update to reflect those changes. Effectively, the UI is a visual representation of the application state as retrieved from the data layer.

However, the application data you get from the data layer is usually in a different format than the information you need to display. For example, you might only need part of the data for the UI, or you might need to merge two different data sources to present information that is relevant to the user. Regardless of the logic you apply, you need to pass the UI all the information it needs to render fully. The UI layer is the pipeline that converts application data changes to a form that the UI can present and then displays it.

presentation layer ui

A basic case study

Consider an app that fetches news articles for a user to read. The app has an articles screen that presents articles available to read, and also allows signed-in users to bookmark articles that really stand out. Given that there may be a lot of articles at any moment in time, the reader should be able to browse articles by category. In summary, the app lets users do the following:

  • View articles available to read.
  • Browse articles by category.
  • Sign in and bookmark certain articles.
  • Access some premium features if eligible.

presentation layer ui

The following sections use this example as a case study to introduce the principles of unidirectional data flow, as well as illustrating the problems that these principles help solve in the context of app architecture for the UI layer.

UI layer architecture

The term UI refers to UI elements such as activities and fragments that display the data, independent of what APIs they use to do this (Views or Jetpack Compose ). Because the role of the data layer is to hold, manage, and provide access to the app data, the UI layer must perform the following steps:

  • Consume app data and transform it into data the UI can easily render.
  • Consume UI-renderable data and transform it into UI elements for presentation to the user.
  • Consume user input events from those assembled UI elements and reflect their effects in the UI data as needed.
  • Repeat steps 1 through 3 for as long as necessary.

The rest of this guide demonstrates how to implement a UI layer that performs these steps. In particular, this guide covers the following tasks and concepts:

  • How to define the UI state.
  • Unidirectional data flow (UDF) as a means of producing and managing the UI state.
  • How to expose UI state with observable data types according to UDF principles.
  • How to implement UI that consumes the observable UI state.

The most fundamental of these is the definition of the UI state.

Define UI state

Refer to the case study outlined earlier. In short, the UI shows a list of articles along with some metadata for each article. This information that the app presents to the user is the UI state.

In other words: if the UI is what the user sees, the UI state is what the app says they should see. Like two sides of the same coin, the UI is the visual representation of the UI state. Any changes to the UI state are immediately reflected in the UI.

UI is a result of binding UI elements on the screen with the UI state.

Consider the case study; in order to fulfill the News app's requirements, the information required to fully render the UI can be encapsulated in a NewsUiState data class defined as follows:

Immutability

The UI state definition in the example above is immutable. The key benefit of this is that immutable objects provide guarantees regarding the state of the application at an instant in time. This frees up the UI to focus on a single role: to read the state and update its UI elements accordingly. As a result, you should never modify the UI state in the UI directly unless the UI itself is the sole source of its data. Violating this principle results in multiple sources of truth for the same piece of information, leading to data inconsistencies and subtle bugs.

For example, if the bookmarked flag in a NewsItemUiState object from the UI state in the case study were updated in the Activity class, that flag would be competing with the data layer as the source of the bookmarked status of an article. Immutable data classes are very useful for preventing this kind of antipattern.

Naming conventions in this guide

In this guide, UI state classes are named based on the functionality of the screen or part of the screen they describe. The convention is as follows:

functionality + UiState .

For example, the state of a screen displaying news might be called NewsUiState , and the state of a news item in a list of news items might be a NewsItemUiState .

Manage state with Unidirectional Data Flow

The previous section established that the UI state is an immutable snapshot of the details needed for the UI to render. However, the dynamic nature of data in apps means that state might change over time. This might be due to user interaction or other events that modify the underlying data that is used to populate the app.

These interactions may benefit from a mediator to process them, defining the logic to be applied to each event and performing the requisite transformations to the backing data sources in order to create UI state. These interactions and their logic may be housed in the UI itself, but this can quickly get unwieldy as the UI starts to become more than its name suggests: it becomes data owner, producer, transformer, and more. Furthermore, this can affect testability because the resulting code is a tightly coupled amalgam with no discernable boundaries. Ultimately, the UI stands to benefit from reduced burden. Unless the UI state is very simple, the UI's sole responsibility should be to consume and display UI state.

This section discusses Unidirectional Data Flow (UDF), an architecture pattern that helps enforce this healthy separation of responsibility.

State holders

The classes that are responsible for the production of UI state and contain the necessary logic for that task are called state holders . State holders come in a variety of sizes depending on the scope of the corresponding UI elements that they manage, ranging from a single widget like a bottom app bar to a whole screen or a navigation destination.

In the latter case, the typical implementation is an instance of a ViewModel , although depending on the requirements of the application, a simple class might suffice. The News app from the case study , for example, uses a NewsViewModel class as a state holder to produce the UI state for the screen displayed in that section.

There are many ways to model the codependency between the UI and its state producer. However, because the interaction between the UI and its ViewModel class can largely be understood as event input and its ensuing state output , the relationship can be represented as shown in the following diagram:

presentation layer ui

The pattern where the state flows down and the events flow up is called a unidirectional data flow (UDF). The implications of this pattern for app architecture are as follows:

  • The ViewModel holds and exposes the state to be consumed by the UI. The UI state is application data transformed by the ViewModel.
  • The UI notifies the ViewModel of user events.
  • The ViewModel handles the user actions and updates the state.
  • The updated state is fed back to the UI to render.
  • The above is repeated for any event that causes a mutation of state.

For navigation destinations or screens, the ViewModel works with repositories or use case classes to get data and transform it into the UI state while incorporating the effects of events that may cause mutations of the state. The case study mentioned earlier contains a list of articles, each having a title, description, source, author name, publication date, and whether it was bookmarked. The UI for each article item looks like this:

A user requesting to bookmark an article is an example of an event that can cause state mutations. As the state producer, it's the ViewModel’s responsibility to define all the logic required in order to populate all fields in the UI state and process the events needed for the UI to render fully.

presentation layer ui

The following sections take a closer look at the events that cause state changes and how they can be processed using UDF.

Types of logic

Bookmarking an article is an example of business logic because it gives value to your app. To learn more about this, see the data layer page. However, there are different types of logic that are important to define:

  • Business logic is the implementation of product requirements for app data. As mentioned already, one example is bookmarking an article in the case study app. Business logic is usually placed in the domain or data layers, but never in the UI layer.
  • UI behavior logic or UI logic is how to display state changes on the screen. Examples include obtaining the right text to show on the screen using Android Resources , navigating to a particular screen when the user clicks a button, or displaying a user message on the screen using a toast or a snackbar .

The UI logic, particularly when it involves UI types like Context , should live in the UI, not in the ViewModel. If the UI grows in complexity and you want to delegate the UI logic to another class to favor testability and separation of concerns, you can create a simple class as a state holder . Simple classes created in the UI can take Android SDK dependencies because they follow the lifecycle of the UI; ViewModel objects have a longer lifespan.

For more information about state holders and how they fit into the context of helping build UI, see the Jetpack Compose State guide .

Why use UDF?

UDF models the cycle of state production as shown in Figure 4. It also separates the place where state changes originate, the place where they are transformed, and the place where they are finally consumed. This separation lets the UI do exactly what its name implies: display information by observing state changes, and relay user intent by passing those changes on to the ViewModel.

In other words, UDF allows for the following:

  • Data consistency. There is a single source of truth for the UI.
  • Testability. The source of state is isolated and therefore testable independent of the UI.
  • Maintainability. Mutation of state follows a well-defined pattern where mutations are a result of both user events and the sources of data they pull from.

Expose UI state

After you define your UI state and determine how you will manage the production of that state, the next step is to present the produced state to the UI. Because you're using UDF to manage the production of state, you can consider the produced state to be a stream—in other words, multiple versions of the state will be produced over time. As a result, you should expose the UI state in an observable data holder like LiveData or StateFlow . The reason for this is so that the UI can react to any changes made in the state without having to manually pull data directly from the ViewModel. These types also have the benefit of always having the latest version of the UI state cached, which is useful for quick state restoration after configuration changes.

For an introduction to LiveData as an observable data holder, see this codelab . For a similar introduction to Kotlin flows, see Kotlin flows on Android .

In cases where the data exposed to the UI is relatively simple, it's often worth wrapping the data in a UI state type because it conveys the relationship between the emission of the state holder and its associated screen or UI element. Furthermore, as the UI element grows more complex, it’s always easier to add to the definition of the UI state to accommodate the extra information needed to render the UI element.

A common way of creating a stream of UiState is by exposing a backing mutable stream as an immutable stream from the ViewModel—for example, exposing a MutableStateFlow<UiState> as a StateFlow<UiState> .

The ViewModel can then expose methods that internally mutate the state, publishing updates for the UI to consume. Take, for example, the case where an asynchronous action needs to be performed; a coroutine can be launched using the viewModelScope , and the mutable state can be updated upon completion.

In the above example, the NewsViewModel class attempts to fetch articles for a certain category and then reflects the result of the attempt—whether success or failure—in the UI state where the UI can react to it appropriately. See the Show errors on the screen section to learn more about error handling.

Additional considerations

In addition to the previous guidance, consider the following when exposing UI state:

A UI state object should handle states that are related to each other. This leads to fewer inconsistencies and it makes the code easier to understand. If you expose the list of news items and the number of bookmarks in two different streams, you might end up in a situation where one was updated and the other was not. When you use a single stream, both elements are kept up to date. Furthermore, some business logic may require a combination of sources. For example, you might need to show a bookmark button only if the user is signed in and that user is a subscriber to a premium news service. You could define a UI state class as follows:

In this declaration, the visibility of the bookmark button is a derived property of two other properties. As business logic gets more complex, having a singular UiState class where all properties are immediately available becomes increasingly important.

UI states: single stream or multiple streams? The key guiding principle for choosing between exposing UI state in a single stream or in multiple streams is the previous bullet point: the relationship between the items emitted. The biggest advantage to a single-stream exposure is convenience and data consistency: consumers of state always have the latest information available at any instant in time. However, there are instances where separate streams of state from the ViewModel might be appropriate:

Unrelated data types: Some states that are needed to render the UI might be completely independent from each other. In cases like these, the costs of bundling these disparate states together might outweigh the benefits, especially if one of these states is updated more frequently than the other.

UiState diffing: The more fields there are in a UiState object, the more likely it is that the stream will emit as a result of one of its fields being updated. Because views don't have a diffing mechanism to understand whether consecutive emissions are different or the same, every emission causes an update to the view. This means that mitigation using the Flow APIs or methods like distinctUntilChanged() on the LiveData might be necessary.

Consume UI state

To consume the stream of UiState objects in the UI, you use the terminal operator for the observable data type that you're using. For example, for LiveData you use the observe() method, and for Kotlin flows you use the collect() method or its variations.

When consuming observable data holders in the UI, make sure you take the lifecycle of the UI into consideration. This is important because the UI shouldn’t be observing the UI state when the view isn’t being displayed to the user. To learn more about this topic, see this blog post . When using LiveData , the LifecycleOwner implicitly takes care of lifecycle concerns. When using flows, it's best to handle this with the appropriate coroutine scope and the repeatOnLifecycle API:

Show in-progress operations

A simple way to represent loading states in a UiState class is with a boolean field:

This flag's value represents the presence or absence of a progress bar in the UI.

Show errors on the screen

Showing errors in the UI is similar to showing in-progress operations because they are both easily represented by boolean values that denote their presence or absence. However, errors might also include an associated message to relay back to the user, or an action associated with them that retries the failed operation. Therefore, while an in-progress operation is either loading or not loading, error states might need to be modeled with data classes that host the metadata appropriate for the context of the error.

For example, consider the example from the previous section which showed a progress bar while fetching articles. If this operation results in an error, you might want to display one or more messages to the user detailing what went wrong.

The error messages might then be presented to the user in the form of UI elements like snackbars . Because this is related to how UI events are produced and consumed, see the UI events page to learn more.

Threading and concurrency

Any work performed in a ViewModel should be main-safe —safe to call from the main thread. This is because the data and domain layers are responsible for moving work to a different thread.

If a ViewModel performs long-running operations, then it is also responsible for moving that logic to a background thread. Kotlin coroutines are a great way to manage concurrent operations, and the Jetpack Architecture Components provide built-in support for them. To learn more about using coroutines in Android apps, see Kotlin coroutines on Android .

Changes in app navigation are often driven by event-like emissions. For example, after a SignInViewModel class performs a sign-in, the UiState might have an isSignedIn field set to true . Triggers like these should be consumed just like the ones covered in the Consume UI state section above, except that the consumption implementation should defer to the Navigation component .

The Paging library is consumed in the UI with a type called PagingData . Because PagingData represents and contains items that can change over time—in other words, it is not an immutable type—it should not be represented in an immutable UI state. Instead, you should expose it from the ViewModel independently in its own stream. See the Android Paging codelab for a specific example of this.

In order to provide fluid and smooth top-level navigation transitions, you might want to wait for the second screen to load data before starting the animation. The Android view framework provides hooks to delay transitions between fragment destinations with the postponeEnterTransition() and startPostponedEnterTransition() APIs. These APIs provide a way to ensure that the UI elements on the second screen (typically an image fetched from the network) are ready to be displayed before the UI animates the transition to that screen. For more details and implementation specifics, see the Android Motion sample .

The following Google samples demonstrate the use of the UI layer. Go explore them to see this guidance in practice:

Recommended for you

  • Note: link text is displayed when JavaScript is off
  • UI State production
  • State holders and UI State {:#mad-arch}
  • Guide to app architecture

Content and code samples on this page are subject to the licenses described in the Content License . Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.

Last updated 2023-07-12 UTC.

  • Engineering Mathematics
  • Discrete Mathematics
  • Operating System
  • Computer Networks
  • Digital Logic and Design
  • C Programming
  • Data Structures
  • Theory of Computation
  • Compiler Design
  • Computer Org and Architecture
  • Computer Network Tutorial

Basics of Computer Network

  • Basics of Computer Networking
  • Introduction to basic Networking Terminology
  • Goals of Networks
  • Basic Characteristics of Computer Networks
  • Challenges of Computer Network
  • Physical Components of Computer Network

Network Hardware and Software

  • Types of Computer Networks
  • LAN Full Form
  • How to Set Up a LAN Network?
  • MAN Full Form in Computer Networking
  • MAN Full Form
  • WAN Full Form
  • Introduction of Internetworking
  • Difference between Internet, Intranet and Extranet
  • Protocol Hierarchies in Computer Network
  • Network Devices (Hub, Repeater, Bridge, Switch, Router, Gateways and Brouter)
  • Introduction of a Router
  • Introduction of Gateways
  • What is a network switch, and how does it work?

Network Topology

  • Types of Network Topology
  • Difference between Physical and Logical Topology
  • What is OSI Model? - Layers of OSI Model
  • Physical Layer in OSI Model
  • Data Link Layer
  • Session Layer in OSI model

Presentation Layer in OSI model

  • Application Layer in OSI Model
  • Protocol and Standard in Computer Networks
  • Examples of Data Link Layer Protocols
  • TCP/IP Model
  • TCP/IP Ports and Its Applications
  • What is TCP (Transmission Control Protocol)?
  • TCP 3-Way Handshake Process
  • Services and Segment structure in TCP
  • TCP Connection Establishment
  • TCP Connection Termination
  • Fast Recovery Technique For Loss Recovery in TCP
  • Difference Between OSI Model and TCP/IP Model

Medium Access Control

  • MAC Full Form
  • Channel Allocation Problem in Computer Network
  • Multiple Access Protocols in Computer Network
  • Carrier Sense Multiple Access (CSMA)
  • Collision Detection in CSMA/CD
  • Controlled Access Protocols in Computer Network

SLIDING WINDOW PROTOCOLS

  • Stop and Wait ARQ
  • Sliding Window Protocol | Set 3 (Selective Repeat)
  • Piggybacking in Computer Networks

IP Addressing

  • What is IPv4?
  • What is IPv6?
  • Introduction of Classful IP Addressing
  • Classless Addressing in IP Addressing
  • Classful Vs Classless Addressing
  • Classless Inter Domain Routing (CIDR)
  • Supernetting in Network Layer
  • Introduction To Subnetting
  • Difference between Subnetting and Supernetting
  • Types of Routing
  • Difference between Static and Dynamic Routing
  • Unicast Routing - Link State Routing
  • Distance Vector Routing (DVR) Protocol
  • Fixed and Flooding Routing algorithms
  • Introduction of Firewall in Computer Network

Congestion Control Algorithms

  • Congestion Control in Computer Networks
  • Congestion Control techniques in Computer Networks
  • Computer Network | Leaky bucket algorithm
  • TCP Congestion Control

Network Switching

  • Circuit Switching in Computer Network
  • Message switching techniques
  • Packet Switching and Delays in Computer Network
  • Differences Between Virtual Circuits and Datagram Networks

Application Layer:DNS

  • Domain Name System (DNS) in Application Layer
  • Details on DNS
  • Introduction to Electronic Mail
  • E-Mail Format
  • World Wide Web (WWW)
  • HTTP Full Form
  • Streaming Stored Video
  • What is a Content Distribution Network and how does it work?

CN Interview Quetions

  • Top 50 Plus Networking Interview Questions and Answers for 2024
  • Top 50 TCP/IP Interview Questions and Answers 2024
  • Top 50 IP Addressing Interview Questions and Answers
  • Last Minute Notes - Computer Networks
  • Computer Network - Cheat Sheet
  • Network Layer
  • Transport Layer
  • Application Layer

Prerequisite : OSI Model

Introduction : Presentation Layer is the 6th layer in the Open System Interconnection (OSI) model. This layer is also known as Translation layer, as this layer serves as a data translator for the network. The data which this layer receives from the Application Layer is extracted and manipulated here as per the required format to transmit over the network. The main responsibility of this layer is to provide or define the data format and encryption. The presentation layer is also called as Syntax layer since it is responsible for maintaining the proper syntax of the data which it either receives or transmits to other layer(s).

Functions of Presentation Layer :

The presentation layer, being the 6th layer in the OSI model, performs several types of functions, which are described below-

  • Presentation layer format and encrypts data to be sent across the network.
  • This layer takes care that the data is sent in such a way that the receiver will understand the information (data) and will be able to use the data efficiently and effectively.
  • This layer manages the abstract data structures and allows high-level data structures (example- banking records), which are to be defined or exchanged.
  • This layer carries out the encryption at the transmitter and decryption at the receiver.
  • This layer carries out data compression to reduce the bandwidth of the data to be transmitted (the primary goal of data compression is to reduce the number of bits which is to be transmitted).
  • This layer is responsible for interoperability (ability of computers to exchange and make use of information) between encoding methods as different computers use different encoding methods.
  • This layer basically deals with the presentation part of the data.
  • Presentation layer, carries out the data compression (number of bits reduction while transmission), which in return improves the data throughput.
  • This layer also deals with the issues of string representation.
  • The presentation layer is also responsible for integrating all the formats into a standardized format for efficient and effective communication.
  • This layer encodes the message from the user-dependent format to the common format and vice-versa for communication between dissimilar systems.
  • This layer deals with the syntax and semantics of the messages.
  • This layer also ensures that the messages which are to be presented to the upper as well as the lower layer should be standardized as well as in an accurate format too.
  • Presentation layer is also responsible for translation, formatting, and delivery of information for processing or display.
  • This layer also performs serialization (process of translating a data structure or an object into a format that can be stored or transmitted easily).

Features of Presentation Layer in the OSI model: Presentation layer, being the 6th layer in the OSI model, plays a vital role while communication is taking place between two devices in a network.

List of features which are provided by the presentation layer are:

  • Presentation layer could apply certain sophisticated compression techniques, so fewer bytes of data are required to represent the information when it is sent over the network.
  • If two or more devices are communicating over an encrypted connection, then this presentation layer is responsible for adding encryption on the sender’s end as well as the decoding the encryption on the receiver’s end so that it can represent the application layer with unencrypted, readable data.
  • This layer formats and encrypts data to be sent over a network, providing freedom from compatibility problems.
  • This presentation layer also negotiates the Transfer Syntax.
  • This presentation layer is also responsible for compressing data it receives from the application layer before delivering it to the session layer (which is the 5th layer in the OSI model) and thus improves the speed as well as the efficiency of communication by minimizing the amount of the data to be transferred.

Working of Presentation Layer in the OSI model : Presentation layer in the OSI model, as a translator, converts the data sent by the application layer of the transmitting node into an acceptable and compatible data format based on the applicable network protocol and architecture.  Upon arrival at the receiving computer, the presentation layer translates data into an acceptable format usable by the application layer. Basically, in other words, this layer takes care of any issues occurring when transmitted data must be viewed in a format different from the original format. Being the functional part of the OSI mode, the presentation layer performs a multitude (large number of) data conversion algorithms and character translation functions. Mainly, this layer is responsible for managing two network characteristics: protocol (set of rules) and architecture.

Presentation Layer Protocols : Presentation layer being the 6th layer, but the most important layer in the OSI model performs several types of functionalities, which makes sure that data which is being transferred or received should be accurate or clear to all the devices which are there in a closed network. Presentation Layer, for performing translations or other specified functions, needs to use certain protocols which are defined below –

  • Apple Filing Protocol (AFP): Apple Filing Protocol is the proprietary network protocol (communications protocol) that offers services to macOS or the classic macOS. This is basically the network file control protocol specifically designed for Mac-based platforms.
  • Lightweight Presentation Protocol (LPP): Lightweight Presentation Protocol is that protocol which is used to provide ISO presentation services on the top of TCP/IP based protocol stacks.
  • NetWare Core Protocol (NCP): NetWare Core Protocol is the network protocol which is used to access file, print, directory, clock synchronization, messaging, remote command execution and other network service functions.
  • Network Data Representation (NDR): Network Data Representation is basically the implementation of the presentation layer in the OSI model, which provides or defines various primitive data types, constructed data types and also several types of data representations.
  • External Data Representation (XDR): External Data Representation (XDR) is the standard for the description and encoding of data. It is useful for transferring data between computer architectures and has been used to communicate data between very diverse machines. Converting from local representation to XDR is called encoding, whereas converting XDR into local representation is called decoding.
  • Secure Socket Layer (SSL): The Secure Socket Layer protocol provides security to the data that is being transferred between the web browser and the server. SSL encrypts the link between a web server and a browser, which ensures that all data passed between them remains private and free from attacks.

author

Please Login to comment...

Similar reads, improve your coding skills with practice.

 alt=

What kind of Experience do you want to share?

Application Architecture Guide - Chapter 10 - Presentation Layer Guidelines

Note - The patterns & practices Microsoft Application Architecture Guide, 2nd Edition is now live at http://msdn.microsoft.com/en-us/library/dd673617.aspx .

- J.D. Meier, Alex Homer, David Hill, Jason Taylor, Prashant Bansode, Lonnie Wall, Rob Boucher Jr, Akshay Bogawat

  • 1 Objectives
  • 3 Presentation Layer Components
  • 5 Design Considerations
  • 6 Presentation Layer Frame
  • 8 Composition
  • 9 Exception Management
  • 12 Navigation
  • 13 Presentation Entities
  • 14 Request Processing
  • 15 User Experience
  • 16 UI Components
  • 17 UI Process Components
  • 18 Validation
  • 19 Pattern Map
  • 20 Pattern Descriptions
  • 21.1 Mobile Applications
  • 21.2 Rich Client Applications
  • 21.3 Rich Internet Applications (RIA)
  • 21.4 Web Applications
  • 22 patterns & practices Solution Assets
  • 23 Additional Resources
  • Understand how the presentation layer fits into typical application architecture.
  • Understand the components of the presentation layer.
  • Learn the steps for designing the presentation layer.
  • Learn the common issues faced while designing the presentation layer.
  • Learn the key guidelines for designing the presentation layer.
  • Learn the key patterns and technology considerations for designing the presentation layer.

The presentation layer contains the components that implement and display the user interface and manage user interaction. This layer includes controls for user input and display, in addition to components that organize user interaction. Figure 1 shows how the presentation layer fits into a common application architecture.

presentation layer ui

Figure 1 A typical application showing the presentation layer and the components it may contain

Presentation Layer Components

  • User interface (UI) components . User interface components provide a way for users to interact with the application. They render and format data for users. They also acquire and validate data input by the user.
  • User process components . User process components synchronize and orchestrate user interactions. Separate user process components may be useful if you have a complicated UI. Implementing common user interaction patterns as separate user process components allows you to reuse them in multiple UIs.

The following steps describe the process you should adopt when designing the presentation layer for your application. This approach will ensure that you consider all of the relevant factors as you develop your architecture:

  • Identify your client type . Choose a client type that satisfies your requirements and adheres to the infrastructure and deployment constraints of your organization. For instance, if your users are on mobile devices and will be intermittently connected to the network, a mobile rich client is probably your best choice.
  • Determine how you will present data . Choose the data format for your presentation layer and decide how you will present the data in your UI.
  • Determine your data-validation strategy . Use data-validation techniques to protect your system from untrusted input.
  • Determine your business logic strategy . Factor out your business logic to decouple it from your presentation layer code.
  • Determine your strategy for communication with other layers . If your application has multiple layers, such as a data access layer and a business layer, determine a strategy for communication between your presentation layer and other layers.

Design Considerations

There are several key factors that you should consider when designing your presentation layer. Use the following principles to ensure that your design meets the requirements for your application, and follows best practices:

  • Choose the appropriate UI technology. Determine if you will implement a rich (smart) client, a Web client, or a rich Internet application (RIA). Base your decision on application requirements, and on organizational and infrastructure constraints.
  • Use the relevant patterns. Review the presentation layer patterns for proven solutions to common presentation problems.
  • Design for separation of concerns. Use dedicated UI components that focus on rendering and display. Use dedicated presentation entities to manage the data required to present your views. Use dedicated UI process components to manage the processing of user interaction.
  • Consider human interface guidelines. Review your organization’s guidelines for UI design. Review established UI guidelines based on the client type and technologies that you have chosen.
  • Adhere to user-driven design principles. Before designing your presentation layer, understand your customer. Use surveys, usability studies, and interviews to determine the best presentation design to meet your customer’s requirements.

Presentation Layer Frame

There are several common issues that you must consider as your develop your design. These issues can be categorized into specific areas of the design. The following table lists the common issues for each category where mistakes are most often made.

Table 1 Presentation Layer Frame

* Caching volatile data.
* Failing to consider use of patterns and libraries that support dynamic layout and injection of views and presentation at runtime.
* Failing to catch unhandled exceptions.
* Failing to design for intuitive use, or implementing overly complex interfaces.
* Using an inappropriate layout style for Web pages.
* Inconsistent navigation.
* Defining entities that are not necessary.
* Blocking the UI during long-running requests.
* Displaying unhelpful error messages.
* Creating custom components that are not necessary.
* Implementing UI process components when not necessary.
* Failing to validate all input.

Caching is one of the best mechanisms you can use to improve application performance and UI responsiveness. Use data caching to optimize data lookups and avoid network round trips. Cache the results of expensive or repetitive processes to avoid unnecessary duplicate processing.

Consider the following guidelines when designing your caching strategy:

  • Do not cache volatile data.
  • Consider using ready-to-use cache data when working with an in-memory cache. For example, use a specific object instead of caching raw database data.
  • Do not cache sensitive data unless you encrypt it.
  • If your application is deployed in Web farm, avoid using local caches that need to be synchronized; instead, consider using a transactional resource manager such as Microsoft SQL Server® or a product that supports distributed caching.
  • Do not depend on data still being in your cache. It may have been removed.

Composition

Consider whether your application will be easier to develop and maintain if the presentation layer uses independent modules and views that are easily composed at run time. Composition patterns support the creation of views and the presentation layout at run time. These patterns also help to minimize code and library dependencies that would otherwise force recompilation and redeployment of a module when the dependencies change. Composition patterns help you to implement sharing, reuse, and replacement of presentation logic and views.

Consider the following guidelines when designing your composition strategy:

  • Avoid using dynamic layouts. They can be difficult to load and maintain.
  • Be careful with dependencies between components. For example, use abstraction patterns when possible to avoid issues with maintainability.
  • Consider creating templates with placeholders. For example, use the Template View pattern to compose dynamic Web pages in order to ensure reuse and consistency.
  • Consider composing views from reusable modular parts. For example, use the Composite View pattern to build a view from modular, atomic component parts.
  • If you need to allow communication between presentation components, consider implementing the Publish/Subscribe pattern. This will lower the coupling between the components and improve testability.

Exception Management

Design a centralized exception-management mechanism for your application that catches and throws exceptions consistently. Pay particular attention to exceptions that propagate across layer or tier boundaries, as well as exceptions that cross trust boundaries. Design for unhandled exceptions so they do not impact application reliability or expose sensitive information.

Consider the following guidelines when designing your exception management strategy:

  • Use user-friendly error messages to notify users of errors in the application.
  • Avoid exposing sensitive data in error pages, error messages, log files, and audit files.
  • Design a global exception handler that displays a global error page or an error message for all unhandled exceptions.
  • Differentiate between system exceptions and business errors. In the case of business errors, display a user-friendly error message and allow the user to retry the operation. In the case of system exceptions, check to see if the exception was caused by issues such as system or database failure, display a user-friendly error message, and log the error message, which will help in troubleshooting.
  • Avoid using exceptions to control application logic.

Design a user input strategy based on your application input requirements. For maximum usability, follow the established guidelines defined in your organization, and the many established industry usability guidelines based on years of user research into input design and mechanisms.

Consider the following guidelines when designing your input collection strategy:

  • Use forms-based input controls for normal data-collection tasks.
  • Use a document-based input mechanism for collecting input in Microsoft Office–style documents.
  • Implement a wizard-based approach for more complex data collection tasks, or for input that requires a workflow.
  • Design to support localization by avoiding hard-coded strings and using external resources for text and layout.
  • Consider accessibility in your design. You should consider users with disabilities when designing your input strategy; for example, implement text-to-speech software for blind users, or enlarge text and images for users with poor sight. Support keyboard-only scenarios where possible for users who cannot manipulate a pointing device.

Design your UI layout so that the layout mechanism itself is separate from the individual UI components and UI process components. When choosing a layout strategy, consider whether you will have a separate team of designers building the layout, or whether the development team will create the UI. If designers will be creating the UI, choose a layout approach that does not require code or the use of development-focused tools.

Consider the following guidelines when designing your layout strategy:

  • Use templates to provide a common look and feel to all of the UI screens.
  • Use a common look and feel for all elements of your UI to maximize accessibility and ease of use.
  • Consider device-dependent input, such as touch screens, ink, or speech, in your layout. For example, with touch-screen input you will typically use larger buttons with more spacing between them than you would with mouse or keyboard inputs.
  • When building a Web application, consider using Cascading Style Sheets (CSS) for layout. This will improve rendering performance and maintainability.
  • Use design patterns, such as Model-View-Presenter (MVP), to separate the layout design from interface processing.

Design your navigation strategy so that users can navigate easily through your screens or pages, and so that you can separate navigation from presentation and UI processing. Ensure that you display navigation links and controls in a consistent way throughout your application to reduce user confusion and hide application complexity.

Consider the following guidelines when designing your navigation strategy:

  • Use well-known design patterns to decouple the UI from the navigation logic where this logic is complex.
  • Design toolbars and menus to help users find functionality provided by the UI.
  • Consider using wizards to implement navigation between forms in a predictable way.
  • Determine how you will preserve navigation state if the application must preserve this state between sessions.
  • Consider using the Command Pattern to handle common actions from multiple sources.

Presentation Entities

Use presentation entities to store the data you will use in your presentation layer to manage your views. Presentation entities are not always necessary; use them only if your datasets are sufficiently large and complex to require separate storage from the UI controls.

Consider the following guidelines when designing presentation entities:

  • Determine if you require presentation entities. Typically, you may require presentation entities only if the data or the format to be displayed is specific to the presentation layer.
  • If you are working with data-bound controls, consider using custom objects, collections, or datasets as your presentation entity format.
  • If you want to map data directly to business entities, use a custom class for your presentation entities.
  • Do not add business logic to presentation entities.
  • If you need to perform data type validation, consider adding it in your presentation entities.

Request Processing

Design your request processing with user responsiveness in mind, as well as code maintainability and testability.

Consider the following guidelines when designing request processing:

  • Use asynchronous operations or worker threads to avoid blocking the UI for long-running actions.
  • Avoid mixing your UI processing and rendering logic.
  • Consider using the Passive View pattern (a variant of MVP) for interfaces that do not manage a lot of data.
  • Consider using the Supervising Controller pattern (a variant of MVP) for interfaces that manage large amounts of data.

User Experience

Good user experience can make the difference between a usable and unusable application. Carry out usability studies, surveys, and interviews to understand what users require and expect from your application, and design with these results in mind.

Consider the following guidelines when designing for user experience:

  • When developing a rich Internet application (RIA), avoid synchronous processing where possible.
  • When developing a Web application, consider using Asynchronous JavaScript and XML (AJAX) to improve responsiveness and to reduce post backs and page reloads.
  • Do not design overloaded or overly complex interfaces. Provide a clear path through the application for each key user scenario.
  • Design to support user personalization, localization, and accessibility.
  • Design for user empowerment. Allow the user to control how he or she interacts with the application, and how it displays data to them.

UI Components

UI components are the controls and components used to display information to the user and accept user input. Be careful not to create custom controls unless it is necessary for specialized display or data collection.

Consider the following guidelines when designing UI components:

  • Take advantage of the data-binding features of the controls you use in the UI.
  • Create custom controls or use third-party controls only for specialized display and data-collection tasks.
  • When creating custom controls, extend existing controls if possible instead of creating a new control.
  • Consider implementing designer support for custom controls to make it easier to develop with them.
  • Consider maintaining the state of controls as the user interacts with the application instead of reloading controls with each action.

UI Process Components

UI process components synchronize and orchestrate user interactions. UI processing components are not always necessary; create them only if you need to perform significant processing in the presentation layer that must be separated from the UI controls. Be careful not to mix business and display logic within the process components; they should be focused on organizing user interactions with your UI.

Consider the following guidelines when designing UI processing components:

  • Do not create UI process components unless you need them.
  • If your UI requires complex processing or needs to talk to other layers, use UI process components to decouple this processing from the UI.
  • Consider dividing UI processing into three distinct roles: Model, View, and Controller/Presenter, by using the MVC or MVP pattern.
  • Avoid business rules, with the exception of input and data validation, in UI processing components.
  • Consider using abstraction patterns, such as dependency inversion, when UI processing behavior needs to change based on the run-time environment.
  • Where the UI requires complex workflow support, create separate workflow components that use a workflow system such as Windows Workflow or a custom mechanism.

Designing an effective input and data-validation strategy is critical to the security of your application. Determine the validation rules for user input as well as for business rules that exist in the presentation layer.

Consider the following guidelines when designing your input and data validation strategy:

  • Validate all input data on the client side where possible to improve interactivity and reduce errors caused by invalid data.
  • Do not rely on client-side validation only. Always use server-side validation to constrain input for security purposes and to make security-related decisions.
  • Design your validation strategy to constrain, reject, and sanitize malicious input.
  • Use the built-in validation controls where possible, when working with .NET Framework.
  • In Web applications, consider using AJAX to provide real-time validation.

Pattern Map

Key patterns are organized by key categories, as detailed in the Presentation Layer Frame in the following table. Consider using these patterns when making design decisions for each category.

Table 2 Pattern Map

* Cache Dependency
* Composite View
* Exception Shielding
* Template View
* Front Controller
* Entity Translator
* Asynchronous Callback
* Model-View-Controller (MVC)
  • For more information on the Page Cache pattern, see “Enterprise Solution Patterns Using Microsoft .NET” at http://msdn.microsoft.com/en-us/library/ms998469.aspx
  • For more information on the Model-View-Controller (MVC), Page Controller, Front Controller, Template View, Transform View, and Two-Step View patterns, see “Patterns of Enterprise Application Architecture (P of EAA)” at http://martinfowler.com/eaaCatalog/
  • For more information on the Composite View, Supervising Controller, and Presentation Model patterns, see “Patterns in the Composite Application Library” at http://msdn.microsoft.com/en-us/library/cc707841.aspx
  • For more information on the Chain of responsibility and Command pattern, see “data & object factory” at http://www.dofactory.com/Patterns/Patterns.aspx
  • For more information on the Asynchronous Callback pattern, see “Creating a Simplified Asynchronous Call Pattern for Windows Forms Applications” at http://msdn.microsoft.com/en-us/library/ms996483.aspx
  • For more information on the Exception Shielding and Entity Translator patterns, see “Useful Patterns for Services” at http://msdn.microsoft.com/en-us/library/cc304800.aspx

Pattern Descriptions

  • Asynchronous Callback. Execute long-running tasks on a separate thread that executes in the background, and provide a function for the thread to call back into when the task is complete.
  • Cache Dependency. Use external information to determine the state of data stored in a cache.
  • Chain of Responsibility. Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.
  • Composite View . Combine individual views into a composite representation.
  • Command Pattern. Encapsulate request processing in a separate command object with a common execution interface.
  • Entity Translator. An object that transforms message data types into business types for requests, and reverses the transformation for responses.
  • Exception Shielding. Prevent a service from exposing information about its internal implementation when an exception occurs.
  • Front Controller . Consolidate request handling by channeling all requests through a single handler object, which can be modified at run time with decorators.
  • Model-View-Controller . Separate the UI code into three separate units: Model (data), View (interface), and Presenter (processing logic), with a focus on the View. Two variations on this pattern include Passive View and Supervising Controller, which define how the View interacts with the Model.
  • Page Cache. Improve the response time for dynamic Web pages that are accessed frequently but change less often and consume a large amount of system resources to construct.
  • Page Controller . Accept input from the request and handle it for a specific page or action on a Web site.
  • Passive View . Reduce the view to the absolute minimum by allowing the controller to process user input and maintain the responsibility for updating the view.
  • Presentation Model . Move all view logic and state out of the view, and render the view through data-binding and templates.
  • Supervising Controller . A variation of the MVC pattern in which the controller handles complex logic, in particular coordinating between views, but the view is responsible for simple view-specific logic.
  • Template View . Implement a common template view, and derive or construct views using this template view.
  • Transform View . Transform the data passed to the presentation tier into HTML for display in the UI.
  • Two-Step View . Transform the model data into a logical presentation without any specific formatting, and then convert that logical presentation to add the actual formatting required.

Technology Considerations

The following guidelines will help you to choose an appropriate implementation technology. The guidelines also contain suggestions for common patterns that are useful for specific types of application and technology.

Mobile Applications

Consider the following guidelines when designing a mobile application:

  • If you want to build full-featured connected, occasionally connected, and disconnected executable applications that run on a wide range of Microsoft Windows®–based devices, consider using the Microsoft Windows Compact Framework.
  • If you want to build connected applications that require Wireless Application Protocol (WAP), compact HTML (cHTML), or similar rendering formats, consider using ASP.NET Mobile Forms and Mobile Controls.
  • If you want to build applications that support rich media and interactivity, consider using Microsoft Silverlight® for Mobile.

Rich Client Applications

Consider the following guidelines when designing a rich client application:

  • If you want to build applications with good performance and interactivity, and have design support in Microsoft Visual Studio®, consider using Windows Forms.
  • If you want to build applications that fully support rich media and graphics, consider using Windows Presentation Foundation (WPF).
  • If you want to build applications that are downloaded from a Web server and then execute on the client, consider using XAML Browser Applications (XBAP).
  • If you want to build applications that are predominantly document-based, or are used for reporting, consider designing a Microsoft Office Business Application.
  • If you decide to use Windows Forms and you are designing composite interfaces, consider using the Smart Client Software Factory.
  • If you decide to use WPF and you are designing composite interfaces, consider using the Composite Application Guidance for WPF.
  • If you decide to use WPF, consider using the Presentation Model (Model-View-ViewModel) pattern.
  • If you decide to use WPF, consider using WPF Commands to communicate between your View and your Presenter or ViewModel.
  • If you decide to use WPF, consider implementing the Presentation Model pattern by using DataTemplates over User Controls to give designers more control.

Rich Internet Applications (RIA)

Consider the following guidelines when designing an RIA:

  • If you want to build browser-based, connected applications that have broad cross-platform reach, are highly graphical, and support rich media and presentation features, consider using Silverlight.
  • If you decide to use Silverlight, consider using the Presentation Model (Model-View-ViewModel) pattern.

Web Applications

Consider the following guidelines when designing a Web application:

  • If you want to build applications that are accessed through a Web browser or specialist user agent, consider using ASP.NET.
  • If you want to build applications that provide increased interactivity and background processing, with fewer page reloads, consider using ASP.NET with AJAX.
  • If you want to build applications that include islands of rich media content and interactivity, consider using ASP.NET with Silverlight controls.
  • If you are using ASP.NET and want to implement a control-centric model with separate controllers and improved testability, consider using the ASP.NET MVC Framework.
  • If you are using ASP.NET, consider using master pages to simplify development and implement a consistent UI across all pages.

patterns & practices Solution Assets

  • Web Client Software Factory at http://msdn.microsoft.com/en-us/library/bb264518.aspx
  • Smart Client Software Factory at http://msdn.microsoft.com/en-us/library/aa480482.aspx
  • Composite Application Guidance for WPF at http://msdn.microsoft.com/en-us/library/cc707819.aspx
  • Smart Client - Composite UI Application Block at http://msdn.microsoft.com/en-us/library/aa480450.aspx

Additional Resources

  • For more information, see Microsoft Inductive User Interface Guidelines at http://msdn.microsoft.com/en-us/library/ms997506.aspx .
  • For more information, see User Interface Control Guidelines at http://msdn.microsoft.com/en-us/library/bb158625.aspx .
  • For more information, see User Interface Text Guidelines at http://msdn.microsoft.com/en-us/library/bb158574.aspx .
  • For more information, see Design and Implementation Guidelines for Web Clients at http://msdn.microsoft.com/en-us/library/ms978631.aspx .
  • For more information, see Web Presentation Patterns at http://msdn.microsoft.com/en-us/library/ms998516.aspx .

Navigation menu

Page actions.

  • View source

Personal tools

  • Community portal
  • Current events
  • Recent changes
  • Random page
  • What links here
  • Related changes
  • Special pages
  • Printable version
  • Permanent link
  • Page information

Powered by MediaWiki

  • This page was last edited on 22 January 2010, at 02:50.
  • Privacy policy
  • About Guidance Share
  • Disclaimers

DZone

  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
  • Manage My Drafts

Low-Code Development: Leverage low and no code to streamline your workflow so that you can focus on higher priorities.

2024 Kubernetes survey: Share your insights on containers, K8s, CI/CD, and DevOps (+ enter a $750 raffle!) for our upcoming Trend Report.

Vector databases: Learn all about the specialized VDBMS — its initial setup, data preparation, collection creation, data querying, and more.

Natural Language Processing: Learn all of the cutting-edge NLP techniques! * Affiliate

  • Hexagonal Architecture in the Frontend: A Real Case
  • Cell-Based Architecture: Comprehensive Guide
  • Are Your ELT Tools Ready for Medallion Data Architecture?
  • Why and How to Transition to SaaS Cloud Enterprise Applications
  • Datafaker Gen: Leveraging BigQuery Sink on Google Cloud Platform
  • Essential Skills for Modern Machine Learning Engineers: A Deep Dive
  • Argo Rollout and Deployment Strategies
  • AI Agentic 101: Understanding Artificial Intelligence Agents
  • Data Engineering

Android App Architecture [Part 4] Presentation Layer

Radivoje Ostojic user avatar

Join the DZone community and get the full member experience.

man-giving-presentation

In the previous articles, I described and implemented the data layer, domain layer, and data and domain modules for one of the features in our application, the WeatherApp. Now, it's time to implement the last missing layer of our app, the presentation layer.

What Is the Presentation Layer?

As the name suggests, this layer is responsible for presenting UI to the user. It's used to perform necessary UI logic based on the data received through the domain layer and user interactions. In the previous article, we described and implemented our domain layer. Our presentation layer depends on it, but the domain shouldn't know anything about the presentation layer. This presentation layer follows the MVVM architecture pattern that we described in our first article. Also, we'll use Android Jetpack to implement this pattern correctly.

First, we need to create a presentation module for our weather feature. In the directory feature, create the module feature_weather . After that, the first step is to update Gradle dependency:

This module should implement necessary dependencies from the core module, and it'll depend on the domain_weather module.

After we finish creating our Gradle file, the next step is to create a presentation model. This presentation model will be mapped from the domain model. Create a package called model inside main/java and a data class, WeatherView , inside it.

To parcel this WeatherView data class, we need to modify the build.gradle of our presentation module. Below android and abode dependency add androidExtensions and set experimental to true:

Now, when we have our presentation model, we can create a design. The design won't be complicated because it's not an essential part of our application. We'll implement a simple screen using ConstraintLayout to display data from the model:

Initial UI

This layout should include two views, view_loading , and view_error . The loading view should have just one rotating progress bar, and an error view should have a simple image viewer with an error image. Set error_view to gone for now.

The next step is to create two fragments, one for loading and one for displaying the weather. First, create a directory called UI under main/java . Inside the UI package, create two more packages, display and load . Inside display , create a file called DisplayWeatherFragment , and inside load create a file, LoadWeatherFragment .

Loading and main views

Inside weather_navigation.xml for DisplayWeatherFragment add an argument for WeatherView . We need to pass a WeatherView object to the DisplayWeatherFragment   screen once it's loaded to display weather data to the user:

To pass a WeatherView instance to the DisplayWeatherFragment , we need to load it from the domain layer. For loading and direct communication to the domain layer, we'll create a view model class inside the load package called LoadWeatherViewModel . First, we'll inject GetWeatherUseCase from the domain layer through the constructor:

To properly implement the observer pattern, we'll use a lifecycle-aware data holder from Android Jetpack, LiveData . Before we use it in our view model, we need to create a LiveData extension in our core module. Inside the core module, under package extensions, create a new file called LiveDataExtensions and add those two extensions:

Once we add those extensions, we can create LiveData for getting weather information in LoadWeatherViewModel :

The next step is to create a public function that will run GetWeatherUseCase and return a Weather   instance or error.

Before we create the handleResult() function, we need to add a constant error string that'll be used in both view model and fragment to identify a connection error:

Now, we can implement the handleResult() function:

The last but important thing is to call clear on getWeatherUseCase() in the overridden method,   onCleared() :

Before we implement LoadWeatherFragment , we need to set up dependency injection for this module because the first thing we do in LoadWeatherFragment will be injecting the LoadWeatherViewModel . Under main/java , create a package called di , and under it, create the first file called WeatherScope :

After WeatherScope , in same package, create a file called WeatherComponent :

This component depends on the domain component. Next, create a WeatherInjector and call it from the Weatherapp module:

Once we're done with dependency injection, we can continue working on our fragments. Using WetherComponent , we can access our view model like this:

Add this line above onCreateView() . Next, override   onActivityCreated() , and call a public method from the view model for getting weather and method to initialize observer inside it:

The weatherReceived function is responsible for performing UI logic based on   Resource.State :

We need to show the loading view while the results load:

When we get an error as a result, we need to preview the error view:

If the error is CONNECTION_ERROR , show the connection error view; otherwise, show the unknown error:

Currently, we don't have different UIs for unknown and connection errors, but it can be easily extended with this logic.

If the result is a success, we'll get a WeatherView instance, navigate to DisplayWeatherFragment , and pass this WeatherView object as an argument:

With this, we're finished with loading data from the view model, and we're done with LoadWeatherFrament . The final step is to extend the function, setUpView() , inside DisplayWeatherFragment to display actual data from our WeatherView object that we received from LoadWeatherFragment :

That is all. We have implemented the last layer of our architecture. In this article, we implemented the presentation layer for weather features following the MVVM design pattern and with the help of Android Jetpack.

Further Reading

  • Java Vs. Kotlin: Which One Will Be the Best in 2019?
  • Android Tutorial – Learn Android From Scratch!

Published at DZone with permission of Radivoje Ostojic . See the original article here.

Opinions expressed by DZone contributors are their own.

Partner Resources

  • About DZone
  • Send feedback
  • Community research
  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone
  • Terms of Service
  • Privacy Policy
  • 3343 Perimeter Hill Drive
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

App Architecture: Presentation layer

presentation layer ui

This is a series of articles about how to architecture your app that it was inspired by Google  Guide to App Architecture  and my personal experience.

Today we finally explore the Presentation layer of our architecture. It contains all UI-related logic and everything the user can see and interact with. This layer is also responsible for interpreting application data to the user-readable form and vice versa, transforming user interaction to the data changes in the app.

presentation layer ui

In this guide, I will demonstrate how to implement and organize a UI layer. There are a lot of libraries, frameworks, and patterns you can use to build a UI layer. Today I’m building everything based on the next tech stack: Android Fragment + Jatpack Compose +  Orbit-MVI  + Kotlin + Flow + Coroutines + Koin (DI). This is one of the optimal combinations. I will focus on the UI’s building blocks such as  Router ,  Router Container, ViewModel, Screen,  and  Navigator.

The Route is the  main UI unit  responsible for:

  • Holding  ViewModel, Navigator , and  Screen  composable with UI elements.
  • Consuming the UI state.
  • Handling  Side Effects  (one-time action).
  • Passing user interaction to the  ViewModel .

The main idea that sits behind the Router is to encapsulate and make a self-sustainable UI unit that knows how to produce and manage the UI state (implement unidirectional data flow) and navigate.

Naming conventions

The Route classes are named after the  Screen  name they’re responsible for.

Screen name + Route.

For example:  FareListRoute ,  ConformationRoute .

@Composable
fun FareListRoute(
navigator: FareListNavigator,
ryderId: String,
viewModel: FareListViewModel = koinViewModel { parametersOf(ryderId) },
scaffoldState: ScaffoldState = rememberScaffoldState(),
) {
val state by viewModel.collectAsState()
FareListScreen(
uiState = state,
scaffoldState = scaffoldState,
onFareClick = viewModel::onFareClick,
)
viewModel.RenderEffect(scaffoldState = scaffoldState, navigator = navigator)
}
@Composable
private fun FareListViewModel.RenderEffect(
scaffoldState: ScaffoldState,
navigator: FareListNavigator,
) {
collectSideEffect { effect ->
when (effect) {
is FareListEffect.GoToConfirmation -> {
navigator.goToConfirmation(ryderId = effect.ryderId, fare = effect.fare)
}
FareListEffect.ShowGeneralNetworkError -> scaffoldState.showSnackBar("Network error")
}
}
}

In the code above you can see what Router looks like. The  ViewModel  passed as a parameter and injected by Koin (DI). Along with it, we pass  Navigator  and  ryderId  as data passed from the previous screen. The one cool feature of the Koin is that you can inject  ryderId  it into  ViewModel  the constructor.

The Router can have more than one  ViewModel .

I’ll cover it in the section about  ViewModel . In the  Router  we collect the state that  ViewModel  holds and pass it as a parameter to the  Screen .

Do not pass  ViewModel  as an argument to the  Screen  composable function. Doing so couples the composable function with the ViewModel type, making it less reusable and harder to test and preview. Also, there would be no clear single source of truth that manages the ViewModel instance.

The  collectAsState  is extension function  ContainerHost  that  ViewModel implement from the Orbit library.

@Composable
fun <STATE : Any, SIDE_EFFECT : Any> ContainerHost<STATE, SIDE_EFFECT>.collectAsState(
lifecycleState: Lifecycle.State = Lifecycle.State.STARTED
): State<STATE> {
return this.collectAsState(lifecycleState)
}

lifecycleState  — The Lifecycle where the restarting collecting from this flow work will be kept alive.

RenderEffect  — another extension function (to be able to call ViewModel extension function) responsible for collecting side effects using  collectSideEffect .

@Composable
fun <STATE : Any, SIDE_EFFECT : Any> ContainerHost<STATE, SIDE_EFFECT>.collectSideEffect(
lifecycleState: Lifecycle.State = Lifecycle.State.STARTED,
action: (suspend (sideEffect: SIDE_EFFECT) -> Unit),
) {
this.collectSideEffect(sideEffect = action, lifecycleState = lifecycleState)
}

The Side Effect is a one-time action often it’s navigation like  GoToConfirmation  screen, show Snack Bar, Toast, and Dialog in some cases.

when (effect) {
is FareListEffect.GoToConfirmation -> {
navigator.goToConfirmation(ryderId = effect.ryderId, fare = effect.fare)
}
FareListEffect.ShowGeneralNetworkError -> scaffoldState.showSnackBar("Network error")
}

The Router Container

The Fragment is the UI container for Route. It can contain DI-injected fields we don’t want to pass to the Router, and hold arguments.

These classes are named after the UI component that they’re responsible for.

UI component name + Fragment.

For example  FareListFragment .

UI component name + Controller.

For example  FareListController .

class FareListFragment : Fragment(R.layout.compose_fragment) {
private val arguments: FareListFragmentArgs by navArgs()
private val navigator: FareListNavigator by inject {
parametersOf(findNavController(), lifecycleScope, requireContext())
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val composeView = ComposeFragmentBinding.bind(view).compose
setAppComposeContent(composeView) {
FareListRoute(navigator = navigator, ryderId = arguments.ryderId)
}
}
}

As you can see the code of fragment classes is small because all UI logic is encapsulated in Route, which makes it easy to change the container implementation.

The Router shouldn’t know navigation implementation details, it should depend on  Navigator .

That is why the injection logic of the navigator is inside the Fragment, not the Router because the navigator requires a Fragment  NavController  to implement navigation logic. It keeps the Router decoupled from the container implementation and allows us to easily change container implementation, for example — using Compose navigation or Controller from  Conductor  lib.

The Navigator is responsible for:

  • Encapsulates navigation logic from the Router.
  • Restricts navigation API for certain screens.
  • Define explicit API for each screen.

If the screen has navigation to another screen, it should have its navigator class. It can be extended from the base  ScreenNavigator  with a default go-back action, can contain other navigators and platform-dependent components like Fragment  NavController .

The navigator classes are named after the Screen name that they’re responsible for:

Screen name + Navigator.

For example  FareListNavigator .

Let’s look at the next diagram that shows the relationship between gradle modules of our app.

presentation layer ui

Here you can see core modules  Core ,  Shared.  The  f eature modules such as  Fare  and  Profile , and the App module.

For example, we have a Fare module with features and one of them has a button for navigation to the profile screen of the user. The user profile page is in the Profile module. How to implement this navigation?

For that, we need to create an interface  ProfileSharedNavigator  that knows how to navigate to the user Profile page, and keep it in the Shared module.

interface ProfileSharedNavigator {
fun goToProfile(userId: String)
}

According to our architecture, the Fare module depends on Shared, so we can use  ProfileSharedNavigator  in the  FareListNavigator .

class FareListNavigator(
private val navController: NavController,
private val profileNavigator: ProfileSharedNavigator,
) : ScreenNavigator(navController) {
fun goToConfirmation(ryderId: String, fare: FareModel) {
navController.navigateSafely(
FareListFragmentDirections.actionFareListFragmentToConfirmationFragment(
ryderId = ryderId,
fare = fare
)
)
}
fun goToProfile(userId: String) {
profileNavigator.goToProfile(userId)
}
}

We pass  ProfileSharedNavigator  to the  FareListNavigator  as one of its arguments and delegate navigation calls to it.

The  ScreenNavigator  is the base class that knows only how to navigate back.

abstract class ScreenNavigator(
private val navController: NavController
) {
open fun goBack() {
navController.navigateUp()
}
}

The  App  module knows everything about everyone in the app. The main purpose of this module is to organize all dependency injection logic between all feature modules in the project.

class AppNavigator(
private val navController: NavController,
) : ProfileSharedNavigator {
override fun goToProfile(userId: String) {
navController.navigateSafely(
FareListFragmentDirections.actionFareListFragmentToProfileFragment(userId)
)
}
}

As you can see  AppNavigator  hold the real implementation of the  ProfileSharedNavigator  interface. We can depend on this interface across different modules, and create real instances of it in the App module following the  Dependency Inversion Principle (DIP) .

The state file contains the UI state data class and for the Side Effects sealed class suites the best. State class can be Parcelable (optional) if you want the state to survive through the configuration changes. All properties should have a default value if it’s possible. Effect class contains one-time action on UI, like navigation, show toast, snack bar, bottom sheet, or dialog. To learn more about Effect you can read  Orbit Side Effect  documentation.

The state classes are named after the UI component type they’re responsible for. The convention is as follows:

UI component name + State.

UI component name + Effect.

For example:  FareListState and  FareListEffect .

@Parcelize
data class FareListState(
val status: ScreenContentStatus = ScreenContentStatus.Idle,
val showRequestLoading: Boolean = false,
val fares: List<FareModel> = emptyList(),
) : Parcelable
sealed class FareListEffect {
data class GoToConfirmation(val ryderId: String, val fare: FareModel) : FareListEffect()
data object ShowGeneralNetworkError : FareListEffect()
}

If your screen has different loading states, better to explicitly split it in your state class. The screen can have few content states, such as  Idle ,  Loading ,  Refreshing ,  Success ,  Failure . After the initial content loading, we might want to make a request to the server and show loading to the user, in that case better to show the loading dialog using a separate  showRequestLoading  property instead of using  status  a field and set  ScreenContentStatus.Loading . The point is not to try to reuse one field to cover different loading cases.

The Presentation layer also has its data models that reflect models from the Domain layer but are more UI-specific. The mapping logic of the presentation model to the domain and vice versa should be placed in the ViewModel class.

@Parcelize
data class FareModel(
val description: String,
val price: Float,
) : Parcelable

Stacked Cards Layout With Compose — And Cats

Stack vs. heap in kotlin: understanding memory, android builds: simple recipes to enhance developer productivity.

Carly Solutions GmbH

Senior Android Engineer

SumUp

Senior Android Developer

Our video recommendation, kobweb:creating websites in kotlin leveraging compose html.

presentation layer ui

Senior Android Developer (all genders)

presentation layer ui

Uber – Staff Android Engineer, Rider

presentation layer ui

Senior Full Stack Developer

presentation layer ui

Backend Engineer – Java/Kotlin (m/f/d)

presentation layer ui

Flutter Developer

Team lead app development (all genders).

presentation layer ui

Expert outils et système d’exploitation Android H/F

presentation layer ui

Senior Cybersecurity Engineer

presentation layer ui

Senior Backend Developer

presentation layer ui

  • The presentation layer shouldn’t expose the UI model to other layers.
  • The presentation model can implement platform-specific ways of serialization such as  Parcelable  and  Serializable .
  • The presentation model should be immutable.

The model classes are named after the data type that they’re responsible for:

type of data + Model.

For example:  Ryder ,  Fare .

The ViewModel is a business logic state holder. In Android development,  ViewModel  is   suitable for providing access to the business logic and preparing the application data for presentation on the screen. Also, process user events and transform data from the data or domain layers to screen UI state.

For the current implementation, I’m using  androidx.lifecycle.ViewModel  and  Orbit-MVI  lib. The ViewModel holds the Orbit container and implements  ContainerHost . Check out  Orbit  API documentation to understand better what going on.

The  ViewModel  classes are named after the UI component type that they’re responsible for:

UI component name + ViewModel.

For example  FareListViewModel .

class FareListViewModel(
private val exceptionHandler: ExceptionHandler,
private val ryderId: String,
private val getFaresByIdUseCase: GetFaresByIdUseCase,
) : ViewModel(), ContainerHost<FareListState, FareListEffect> {
override val container: Container<FareListState, FareListEffect> = container(
initialState = FareListState(),
buildSettings = {
this.exceptionHandler =
this@FareListViewModel.exceptionHandler.asCoroutineExceptionHandler()
},
) {
fetchFares()
}
private fun fetchFares() = intent {
reduce { state.copy(status = ScreenContentStatus.Loading) }
executeUseCase { getFaresByIdUseCase(ryderId).asPresentation() }
.onSuccess { fares ->
reduce {
state.copy(
status = ScreenContentStatus.Success,
fares = fares
)
}
}
.onFailure {
reduce { state.copy(status = ScreenContentStatus.Failure) }
postSideEffect(FareListEffect.ShowGeneralNetworkError)
}
}
fun onFareClick(fare: FareModel) = intent {
postSideEffect(FareListEffect.GoToConfirmation(ryderId, fare))
}
}

In the code above you can see the example of ViewModel. Let’s shed light on what is going on there.

Let’s start with the constructor. As you can see we inject the use case from the domain layer,  ryderId  which we pass from the previous screen, and ExceptionHandler. The ViewModel can have multiple use cases.

If you end up in a situation where you have 10+ use cases in the ViewModel, it’s a signal for you to split your ViewModel on few smaller.

Do not try to put some use cases to wrapper classes like this:

data class UseCaseHolder(
private val usecase1: UseCase1,
private val usecase2: UseCase2,
private val usecase3: UseCase3,
)

and then put it in your ViewModel

class FareListViewModel(
private val useCaseHolder: UseCaseHolder,
)

The more interesting stuff going on in  fetchFares  method.

private fun fetchFares() = intent {
reduce { state.copy(status = ScreenContentStatus.Loading) }
executeUseCase { getFaresByIdUseCase(ryderId).asPresentation() }
.onSuccess { fares ->
reduce {
state.copy(
status = ScreenContentStatus.Success,
fares = fares
)
}
}
.onFailure {
reduce { state.copy(status = ScreenContentStatus.Failure) }
postSideEffect(FareListEffect.ShowGeneralNetworkError)
}
}

A few words about Orbit lib API. The  intent  method is executed lambda on  Dispatcher.Default . The  reduce  a method is executed lambda on  Dispatcher.Main . It reduces the state and updates the UI state.

Do not execute the use case in the lambda of  reduce  the method.

The  executeUseCase  is an extension method of ViewModel to execute the use case and wrap its result to  kotlin.Result<R> . It allows you to use extension methods of the Result class such as  onSuccess ,  onFailure . Also, pass the exception to the ViewModel handler.

suspend inline fun <R> ViewModel.executeUseCase(block: () -> R): Result<R> =
viewModelScope.executeUseCase(block)
suspend inline fun <R> CoroutineScope.executeUseCase(block: () -> R): Result<R> {
return runSuspendCatching(block)
.onFailure { e ->
coroutineScope { coroutineContext }.let { coroutineContext ->
coroutineContext[CoroutineExceptionHandler]?.run {
handleException(coroutineContext, e)
}
}
}
}
inline fun <R> runSuspendCatching(block: () -> R): Result<R> {
return try {
Result.success(block())
} catch (cancellationException: CancellationException) {
throw cancellationException
} catch (e: Throwable) {
Result.failure(e)
}
}
The  executeUseCase  method intended to execute only one use case.

If you face a situation when you need to execute 2+ use cases for one operation then you should consider the following options:

  • Create a new use case, put all the logic there, and combine the use case you need.
  • If you need to wait for results from multiple use cases and combine them:
private fun fetchData() = intent {
reduce { state.copy(status = ScreenContentStatus.Loading) }
val fetched = coroutineScope {
awaitAll(
async { fetchUser() },
async { fetchFares() },
).all { it }
}
reduce {
state.copy(
status = if (fetched) {
ScreenContentStatus.Success
} else {
ScreenContentStatus.Failure
}
)
}
}
private suspend fun SimpleSyntax<FareListState, FareListEffect>.fetchFares(): Boolean =
executeUseCase { getFaresByIdUseCase(ryderId).asPresentation() }
.onSuccess { fares -> reduce { state.copy(fares = fares) } }
.onFailure { /* Handle error */ }
.isSuccess
private suspend fun SimpleSyntax<FareListState, FareListEffect>.fetchUser(): Boolean =
executeUseCase { getUserUseCase(userId).asPresentation() }
.onSuccess { user -> reduce { state.copy(user = user) } }
.isSuccess

The  asPresentation()  method responsible for mapping the data model from the domain layer to the model of the presentation layer. You can read how to pam data between layers  here .

The Screen file contains all UI-composed implementations with a Compose preview of each screen state like empty, error, loading, and content.

The screen classes are named after the UI component type that they’re responsible for:

UI component name + Screen.

For example  FareListScreen .

@Composable
fun FareListScreen(
uiState: FareListState,
scaffoldState: ScaffoldState = rememberScaffoldState(),
onFareClick: (FareModel) -> Unit,
) {
Scaffold(
modifier = Modifier.statusBarsPadding(),
scaffoldState = scaffoldState,
topBar = {
TopAppBar(
title = {
Text(text = stringResource(id = R.string.select_fare_title))
},
backgroundColor = AppTheme.colors.material.surface,
)
},
content = {
ScreenContent(
status = uiState.status,
forceLoading = uiState.status.isLoading,
) {
FareList(
fares = uiState.fares,
onClick = onFareClick
)
}
}
)
}
@Preview(name = "Fares Content", showBackground = true)
@Composable
fun PreviewFareListScreenSuccess() {
AppTheme {
FareListScreen(
uiState = FareListState(
status = ScreenContentStatus.Success,
fares = fakeFareModels,
),
onFareClick = {}
)
}
}
@Preview(name = "Fares Content", showBackground = true)
@Composable
fun PreviewFareListScreenLoading() {
AppTheme {
FareListScreen(
uiState = FareListState(
status = ScreenContentStatus.Loading,
fares = fakeFareModels,
),
onFareClick = {}
)
}
}
@Preview(name = "Fares Content", showBackground = true)
@Composable
fun PreviewFareListScreenFailure() {
AppTheme {
FareListScreen(
uiState = FareListState(
status = ScreenContentStatus.Failure,
fares = fakeFareModels,
),
onFareClick = {}
)
}
}

There are a few rules I recommend you follow when building your UI using Compose.

  • Choose stateless composable over stateful. You can read more about it  here .
  • Pass all callbacks up to the top screen composable and pass all user interaction to the ViewModel on the Router level.
  • Make composable previews for different states of UI components.

Imagine we need to write  TopAppBar  Composable function with  title  as parameter. There are two ways you can consider, pass  title  as a String or  @Composable () -> Unit  function.

@Composable
fun TopAppBar(
modifier: Modifier = Modifier,
title: String = "",
) {
Text(text = title)
}
Scaffold(
topBar = {
TopAppBar(
title = stringResource(id = R.string.select_fare_title),
)
},
)
@Composable
fun TopAppBar(
modifier: Modifier = Modifier,
title: @Composable () -> Unit = {},
) {
}
Scaffold(
topBar = {
TopAppBar(
title = { Text(text = stringResource(id = R.string.select_fare_title)) },
)
},
)

Always choose option 2.  It will make your Composable function more customizable and robust at the same time.

Screen preview

To make the screen preview look as close as possible to the real-world scenario we need some random data to create a state. For that, you can create  FareModelFake  class, put it in the same package as  FareModel .

The  FareModelFake  class contains  FareModel  with fake data that you can use for your previews.

internal val fakeFareModels: List<FareModel>
get() = listOf(
FareModel(
description = "2.5 Hour Ticket",
price = 2.5f,
),
FareModel(
description = "1 Day Pass",
price = 5.0f,
),
FareModel(
description = "30 Day Pass",
price = 100f,
)
)

Packaging conventions

Wrapping up.

There are a lot of different ways to implement the Presentation layer. Today I shared with you some ideas on how the Presentation layer can be done. You can follow this approach or use some ideas in your implementation.

You can check the sample project on  github .

Stay tuned for the next App Architecture topic to cover.

This artice is previously published on proandroiddev.com

YOU MAY BE INTERESTED IN

Swipe to dismiss — jetpack compose, make sure to update your stateflow safely in kotlin, the definitive guide of android ui automator with kotlin, basic drag-n-drop in jetpack compose.

' src=

View all posts

' src=

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Post Comment

  Layer 6 Presentation Layer

De/Encryption, Encoding, String representation

The presentation layer (data presentation layer, data provision level) sets the system-dependent representation of the data (for example, ASCII, EBCDIC) into an independent form, enabling the syntactically correct data exchange between different systems. Also, functions such as data compression and encryption are guaranteed that data to be sent by the application layer of a system that can be read by the application layer of another system to the layer 6. The presentation layer. If necessary, the presentation layer acts as a translator between different data formats, by making an understandable for both systems data format, the ASN.1 (Abstract Syntax Notation One) used.

OSI Layer 6 - Presentation Layer

The presentation layer is responsible for the delivery and formatting of information to the application layer for further processing or display. It relieves the application layer of concern regarding syntactical differences in data representation within the end-user systems. An example of a presentation service would be the conversion of an EBCDIC-coded text computer file to an ASCII-coded file. The presentation layer is the lowest layer at which application programmers consider data structure and presentation, instead of simply sending data in the form of datagrams or packets between hosts. This layer deals with issues of string representation - whether they use the Pascal method (an integer length field followed by the specified amount of bytes) or the C/C++ method (null-terminated strings, e.g. "thisisastring\0"). The idea is that the application layer should be able to point at the data to be moved, and the presentation layer will deal with the rest. Serialization of complex data structures into flat byte-strings (using mechanisms such as TLV or XML) can be thought of as the key functionality of the presentation layer. Encryption is typically done at this level too, although it can be done on the application, session, transport, or network layers, each having its own advantages and disadvantages. Decryption is also handled at the presentation layer. For example, when logging on to bank account sites the presentation layer will decrypt the data as it is received.[1] Another example is representing structure, which is normally standardized at this level, often by using XML. As well as simple pieces of data, like strings, more complicated things are standardized in this layer. Two common examples are 'objects' in object-oriented programming, and the exact way that streaming video is transmitted. In many widely used applications and protocols, no distinction is made between the presentation and application layers. For example, HyperText Transfer Protocol (HTTP), generally regarded as an application-layer protocol, has presentation-layer aspects such as the ability to identify character encoding for proper conversion, which is then done in the application layer. Within the service layering semantics of the OSI network architecture, the presentation layer responds to service requests from the application layer and issues service requests to the session layer. In the OSI model: the presentation layer ensures the information that the application layer of one system sends out is readable by the application layer of another system. For example, a PC program communicates with another computer, one using extended binary coded decimal interchange code (EBCDIC) and the other using ASCII to represent the same characters. If necessary, the presentation layer might be able to translate between multiple data formats by using a common format. Wikipedia
  • Data conversion
  • Character code translation
  • Compression
  • Encryption and Decryption

The Presentation OSI Layer is usually composed of 2 sublayers that are:

CASE common application service element

ACSEAssociation Control Service Element
ROSERemote Operation Service Element
CCRCommitment Concurrency and Recovery
RTSEReliable Transfer Service Element

SASE specific application service element

FTAMFile Transfer, Access and Manager
VTVirtual Terminal
MOTISMessage Oriented Text Interchange Standard
CMIPCommon Management Information Protocol
JTMJob Transfer and Manipulation
MMSManufacturing Messaging Service
RDARemote Database Access
DTPDistributed Transaction Processing

Layer 7   Application Layer

Layer 6   presentation layer, layer 5   session layer, layer 4   transport layer, layer 3   network layer, layer 2   data link layer, layer 1   physical layer.

DEV Community

DEV Community

Dino Dujmovic

Posted on May 5, 2023 • Updated on May 7, 2023

Angular Architecture - Abstraction layers

digitaldino

Angular Architecture - Organizing modules

Dino dujmovic ・ apr 18 ・ 5 min read.

Now that we have explored how modular design can be achieved in a standalone Angular application, let's take a closer look at how our application operates and functions by examining it through the lens of abstraction layers .

Abstraction Layers

The concept behind this pattern is to divide the application into discrete layers and establish communication protocols between them.

The pattern aims to split the application into three distinct layers, namely:

  • Abstraction Layer
  • Presentation Layer

abstraction layers data flow

Angular Architecture - Core Module

Dino dujmovic ・ apr 28 ・ 2 min read.

The Core Layer is the central implementation hub for the core application logic, including all data manipulation and external communication. This layer also includes essential business logic, such as API calls for data retrieval.

It's main parts are services for making API calls and/or state management which in case of Angular could be NgRx, NgXs, custom implementation using Subjects or other.

  • API Services have sole purpose to facilitate communication with API endpoints and nothing more.

Movie Service

  • State Management Solution serves as a centralized, immutable data store for the application. By incorporating an Abstraction Layer, we can render our components independent of both the State Management Solution and API/Data Services. This approach makes it much easier to migrate to other data management solutions in the future, as we won't need to modify the Presentational Layer (i.e., the Components).

state management

Abstraction layer

The abstraction layer sits between the presentation and the core layer and handles communication between them. Since, the goal is not to inject API and state providers directly in the presentation layer, rather, we can inject the facade service and use it to interact with the core layer.

So abstraction layer:

  • is implemented as Angular providers/services named facades (example: movies.facade.ts)
  • exposes streams of state and interface
  • is used to store and dispatch actions, observable emissions and expose observables and signals for components to use.

Movies facade

Presentation layer

The presentation layer (UI) layer is where all Angular components reside. Its primary responsibility is to present the application's UI and delegate user actions to the core layer through the abstraction layer.

Inside of presentation layer we have:

Smart/container components:

  • can pass data down to dumb components
  • have facade/s and other services injected
  • communicate with core layer through facades
  • react to events from dumb components
  • are usually page components (meaning they are routable but it is not case)

Smart components

Angular Architecture - Page Modules

Dino dujmovic ・ apr 25 ・ 3 min read.

Dumb/presentational components:

  • recieve their data through @Input() and pass events and data through @Output()
  • do not contain any application logic
  • mostly kept in SharedModule or at specific module components folder

Dumb component

Angular Architecture - Shared Module

Dino dujmovic ・ apr 30 ・ 2 min read.

Example

References:

dev-academy.com/angular-architecture

medium.com/@getrohith.sathya

blog.brecht.io/scalable-angular2

Top comments (1)

pic

Templates let you quickly answer FAQs or store snippets for re-use.

hanneslim profile image

  • Joined Aug 4, 2020

In addition I would highly recommend using a Facade pattern: nerd-corner.com/how-to-build-a-pus...

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink .

Hide child comments as well

For further actions, you may consider blocking this person and/or reporting abuse

jojo97 profile image

CSS basics for non-web designers

Jojo - Jul 18

rn_dev_lalit profile image

Exploring the Exciting New Additions in React 19

Lalit Suthar - Jul 18

sephjoe12 profile image

JavaScript Loops for Beginners: Learn the Basics

Sephjoe - Jul 17

__zamora__ profile image

Intern level: Routing with React Router

Zamora - Jul 17

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

data use cases

Web Application Architecture: How the Web Works

  • Engineering
  • Published: 25 Jul, 2019
  • No comments Share

What is Web Application Architecture?

  • addresses a particular problem, even if it’s simply finding some information
  • is as interactive as a desktop application
  • has a Content Management System

How does the web request work?

web request-response cycle

Web request-response cycle

Web application architecture components and Three-Tier Architecture

web application architecture

Web application architecture following the three-tier pattern

Presentation layer

Business layer, persistence layer, example #1. dynamic web pages, spas, and mpas, single page applications.

SPA architecture

Single Page Application architecture

Multi-Page Applications

multi-page applications

MPA architecture

Example #2. Enterprise applications

enterprise application architecture

Enterprise application architecture

To conclude

Software Architecture Patterns by

Get full access to Software Architecture Patterns and 60K+ other titles, with a free 10-day trial of O'Reilly.

There are also live events, courses curated by job role, and more.

Chapter 1. Layered Architecture

The most common architecture pattern is the layered architecture pattern, otherwise known as the n-tier architecture pattern. This pattern is the de facto standard for most Java EE applications and therefore is widely known by most architects, designers, and developers. The layered architecture pattern closely matches the traditional IT communication and organizational structures found in most companies, making it a natural choice for most business application development efforts. 

Pattern Description

Components within the layered architecture pattern are organized into horizontal layers, each layer performing a specific role within the application (e.g., presentation logic or business logic). Although the layered architecture pattern does not specify the number and types of layers that must exist in the pattern, most layered architectures consist of four standard layers: presentation, business, persistence, and database ( Figure 1-1 ). In some cases, the business layer and persistence layer are combined into a single business layer, particularly when the persistence logic (e.g., SQL or HSQL) is embedded within the business layer components. Thus, smaller applications may have only three layers, whereas larger and more complex business applications may contain five or more layers. 

Each layer of the layered architecture pattern has a specific role and responsibility within the application. For example, a presentation layer would be responsible for handling all user interface and browser communication logic, whereas a business layer would be responsible for executing specific business rules associated with the request. Each layer in the architecture forms an abstraction around the work that needs to be done to satisfy a particular business request. For example, the presentation layer doesn’t need to know or worry about how to get customer data; it only needs to display that information on a screen in particular format. Similarly, the business layer doesn’t need to be concerned about how to format customer data for display on a screen or even where the customer data is coming from; it only needs to get the data from the persistence layer, perform business logic against the data (e.g., calculate values or aggregate data), and pass that information up to the presentation layer.  

Alt Text

Figure 1-1. Layered architecture pattern

One of the powerful features of the layered architecture pattern is the separation of concerns among components. Components within a specific layer deal only with logic that pertains to that layer. For example, components in the presentation layer deal only with presentation logic, whereas components residing in the business layer deal only with business logic. This type of component classification makes it easy to build effective roles and responsibility models into your architecture, and also makes it easy to develop, test, govern, and maintain applications using this architecture pattern due to well-defined component interfaces and limited component scope.

Key Concepts

Notice in Figure 1-2 that each of the layers in the architecture is marked as being  closed . This is a very important concept in the layered architecture pattern. A closed layer means that as a request moves from layer to layer, it must go through the layer right below it to get to the next layer below that one. For example, a request originating from the presentation layer must first go through the business layer and then to the persistence layer before finally hitting the database layer. 

Alt Text

Figure 1-2. Closed layers and request access

So why not allow the presentation layer direct access to either the persistence layer or database layer? After all, direct database access from the presentation layer is much faster than going through a bunch of unnecessary layers just to retrieve or save database information. The answer to this question lies in a key concept known as  layers of isolation . 

The layers of isolation concept means that changes made in one layer of the architecture generally don’t impact or affect components in other layers: the change is isolated to the components within that layer, and possibly another associated layer (such as a persistence layer containing SQL). If you allow the presentation layer direct access to the persistence layer, then changes made to SQL within the persistence layer would impact both the business layer and the presentation layer, thereby producing a very tightly coupled application with lots of interdependencies between components. This type of architecture then becomes very hard and expensive to change.  

The layers of isolation concept also means that each layer is independent of the other layers, thereby having little or no knowledge of the inner workings of other layers in the architecture. To understand the power and importance of this concept, consider a large refactoring effort to convert the presentation framework from JSP (Java Server Pages) to JSF (Java Server Faces). Assuming that the contracts (e.g., model) used between the presentation layer and the business layer remain the same, the business layer is not affected by the refactoring and remains completely independent of the type of user-interface framework used by the presentation layer.  

While closed layers facilitate layers of isolation and therefore help isolate change within the architecture, there are times when it makes sense for certain layers to be open. For example, suppose you want to add a shared-services layer to an architecture containing common service components accessed by components within the business layer (e.g., data and string utility classes or auditing and logging classes). Creating a services layer is usually a good idea in this case because architecturally it restricts access to the shared services to the business layer (and not the presentation layer). Without a separate layer, there is nothing architecturally that restricts the presentation layer from accessing these common services, making it difficult to govern this access restriction.  

In this example, the new services layer would likely reside  below  the business layer to indicate that components in this services layer are not accessible from the presentation layer. However, this presents a problem in that the business layer is now required to go through the services layer to get to the persistence layer, which makes no sense at all. This is an age-old problem with the layered architecture, and is solved by creating open layers within the architecture.  

As illustrated in Figure 1-3 , the services layer in this case is marked as open,  meaning requests are allowed to bypass this open layer and go directly to the layer below it. In the following example, since the services layer is open, the business layer is now allowed to bypass it and go directly to the persistence layer, which makes perfect sense.  

Alt Text

Figure 1-3. Open layers and request flow

Leveraging the concept of open and closed layers helps define the relationship between architecture layers and request flows and also provides designers and developers with the necessary information to understand the various layer access restrictions within the architecture. Failure to document or properly communicate which layers in the architecture are open and closed (and why) usually results in tightly coupled and brittle architectures that are very difficult to test, maintain, and deploy.

Pattern Example

To illustrate how the layered architecture works, consider a request from a business user to retrieve customer information for a particular individual as illustrated in Figure 1-4 . The black arrows show the request flowing down to the database to retrieve the customer data, and the red arrows show the response flowing back up to the screen to display the data. In this example, the customer information consists of both customer data and order data (orders placed by the customer).  

The customer screen is responsible for accepting the request and displaying the customer information. It does not know where the data is, how it is retrieved, or how many database tables must be queries to get the data. Once the customer screen receives a request to get customer information for a particular individual, it then forwards that request onto the customer delegate module. This module is responsible for knowing which modules in the business layer can process that request and also how to get to that module and what data it needs (the contract). The customer object in the business layer is responsible for aggregating all of the information needed by the business request (in this case to get customer information). This module calls out to the  customer dao  (data access object) module in the persistence layer to get customer data, and also the order dao module to get order information. These modules in turn execute SQL statements to retrieve the corresponding data and pass it back up to the customer object in the business layer. Once the customer object receives the data, it aggregates the data and passes that information back up to the customer delegate, which then passes that data to the customer screen to be presented to the user.      

Alt Text

Figure 1-4. Layered architecture example

From a technology perspective, there are literally dozens of ways these modules can be implemented. For example, in the Java platform, the customer screen can be a (JSF) Java Server Faces screen coupled with the customer delegate as the managed bean component. The customer object in the business layer can be a local Spring bean or a remote EJB3 bean. The data access objects illustrated in the previous example can be implemented as simple POJO’s (Plain Old Java Objects), MyBatis XML Mapper files, or even objects encapsulating raw JDBC calls or Hibernate queries. From a Microsoft platform perspective, the customer screen can be an ASP (active server pages) module using the .NET framework to access C# modules in the business layer, with the customer and order data access modules implemented as ADO (ActiveX Data Objects). 

Considerations

The layered architecture pattern is a solid general-purpose pattern, making it a good starting point for most applications, particularly when you are not sure what architecture pattern is best suited for your application. However, there are a couple of things to consider from an architecture standpoint when choosing this pattern.

The first thing to watch out for is what is known as the architecture sinkhole anti-pattern . This anti-pattern describes the situation where requests flow through multiple layers of the architecture as simple pass-through processing with little or no logic performed within each layer. For example, assume the presentation layer responds to a request from the user to retrieve customer data. The presentation layer passes the request to the business layer, which simply passes the request to the persistence layer, which then makes a simple SQL call to the database layer to retrieve the customer data. The data is then passed all the way back up the stack with no additional processing or logic to aggregate, calculate, or transform the data. 

Every layered architecture will have at least some scenarios that fall into the architecture sinkhole anti-pattern. The key, however, is to analyze the percentage of requests that fall into this category. The 80-20 rule is usually a good practice to follow to determine whether or not you are experiencing the architecture sinkhole anti-pattern. It is typical to have around 20 percent of the requests as simple pass-through processing and 80 percent of the requests having some business logic associated with the request. However, if you find that this ratio is reversed and a majority of your requests are simple pass-through processing, you might want to consider making some of the architecture layers open, keeping in mind that it will be more difficult to control change due to the lack of layer isolation. 

Another consideration with the layered architecture pattern is that it tends to lend itself toward monolithic applications, even if you split the presentation layer and business layers into separate deployable units. While this may not be a concern for some applications, it does pose some potential issues in terms of deployment, general robustness and reliability, performance, and scalability.   

Pattern Analysis

The following table contains a rating and analysis of the common architecture characteristics for the layered architecture pattern. The rating for each characteristic is based on the natural tendency for that characteristic as a capability based on a typical implementation of the pattern, as well as what the pattern is generally known for. For a side-by-side comparison of how this pattern relates to other patterns in this report, please refer to  Appendix A  at the end of this report.

Get Software Architecture Patterns now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.

Don’t leave empty-handed

Get Mark Richards’s Software Architecture Patterns ebook to better understand how to design components—and how they should interact.

It’s yours, free.

Cover of Software Architecture Patterns

Check it out now on O’Reilly

Dive in for free with a 10-day trial of the O’Reilly learning platform—then explore all the other resources our members count on to build skills and solve problems every day.

presentation layer ui

NDepend Blog

Improve your .NET code quality with NDepend

Software_architecture_5_patterns_you_need_to_know

Software Architecture: The 5 Patterns You Need to Know

Share this:.

When I was attending night school to become a programmer, I learned several design patterns : singleton, repository, factory, builder, decorator, etc. Design patterns give us a proven solution to existing and recurring problems. What I didn’t learn was that a similar mechanism exists on a higher level in the form of the software architecture pattern .

These are patterns for the overall layout of your application or applications. They all have advantages and disadvantages. And they all address specific issues.

In this post, we’ll take a look at 5 such patterns in detail.  For each software architecture pattern, this will include a description, its advantages, its disadvantages, and the situation for which it is ideal.  The patterns are as follows.

  • The Layered Architectural Pattern
  • The Microkernel Architectural Pattern
  • The CQRS Architectural Pattern
  • The Event Sourcing Architectural Pattern
  • The Microservices Architectural Pattern

Download the NDepend trial for free and use dependency graphs to get a feel for what your software architecture really looks like.

1. The Layered Architectural Pattern

The layered pattern is probably one of the most well-known software architecture patterns.

Many developers use it, without really knowing its name. The idea is to split up your code into “layers”, where each layer has a certain responsibility and provides a service to a higher layer.

There isn’t a predefined number of layers, but these are the ones you see most often:

  • Presentation or UI layer
  • Application layer
  • Business or domain layer
  • Persistence or data access layer
  • Database layer

The idea is that the user initiates a piece of code in the presentation layer by performing some action (e.g. clicking a button). The presentation layer then calls the underlying layer, i.e. the application layer.

Then we go into the business layer and finally, the persistence layer stores everything in the database. So higher layers are dependent upon and make calls to the lower layers.

presentation layer ui

You will see variations of this, depending on the complexity of the applications. Some applications might omit the application layer, while others add a caching layer.

It’s even possible to merge two layers into one. For example, the ActiveRecord pattern combines the business and persistence layers.

Layer Responsibility

As mentioned, each layer has its own responsibility.

The presentation layer contains the graphical design of the application, as well as any code to handle user interaction. You shouldn’t add logic that is not specific to the user interface in this layer.

The business layer is where you put the models and logic that is specific to the business problem you are trying to solve.

The application layer sits between the presentation layer and the business layer.

On the one hand, it provides an abstraction so that the presentation layer doesn’t need to know the business layer. In theory, you could change the technology stack of the presentation layer without changing anything else in your application (e.g. change from WinForms to WPF).

On the other hand, the application layer provides a place to put certain coordination logic that doesn’t fit in the business or presentation layer.

presentation layer ui

Finally, the persistence layer contains the code to access the database layer. The database layer is the underlying database technology (e.g. SQL Server, MongoDB). The persistence layer is the set of code to manipulate the database: SQL statements, connection details, etc.

  • Most developers are familiar with this pattern.
  • It provides an easy way of writing a well-organized and testable application .

Disadvantages

  • It tends to lead to monolithic applications that are hard to split up afterward.
  • Developers often find themselves writing a lot of code to pass through the different layers, without adding any value in these layers. If all you are doing is writing a simple CRUD application, the layered pattern might be overkill for you.
  • Standard line-of-business apps that do more than just CRUD operations

2. The Microkernel Architectural Pattern

The microkernel pattern, or plug-in pattern, is useful when your application has a core set of responsibilities and a collection of interchangeable parts on the side. The microkernel will provide the entry point and the general flow of the application, without really knowing what the different plug-ins are doing.

presentation layer ui

An example is a task scheduler.

The microkernel could contain all the logic for scheduling and triggering tasks, while the plug-ins contain specific tasks. As long as the plug-ins adhere to a predefined API, the microkernel can trigger them without needing to know the implementation details.

Another example is a workflow. The implementation of a workflow contains concepts like the order of the different steps, evaluating the results of steps, deciding what the next step is, etc. The specific implementation of the steps is less important to the core code of the workflow.

  • This pattern provides great flexibility and extensibility.
  • Some implementations allow for adding plug-ins while the application is running.
  • Microkernel and plug-ins can be developed by separate teams.
  • It can be difficult to decide what belongs in the microkernel and what doesn’t.
  • The predefined API might not be a good fit for future plug-ins.
  • Applications that take data from different sources, transform that data and writes it to different destinations
  • Workflow applications
  • Task and job scheduling applications

3. The CQRS Architectural Pattern

CQRS is an acronym for Command and Query Responsibility Segregation . The central concept of this pattern is that an application has read operations and write operations that must be totally separated.

This also means that the model used for write operations (commands) will differ from the read models (queries). Furthermore, the data will be stored in different locations. In a relational database, this means there will be tables for the command model and tables for the read model. Some implementations even store the different models in totally different databases, e.g. SQL Server for the command model and MongoDB for the read model.

This pattern is often combined with event sourcing, which we’ll cover below.

How does it work exactly?

presentation layer ui

When the application needs to show data to the user, it can retrieve the read model by calling the read service, as shown below.

  • Command models can focus on business logic and validation while read models can be tailored to specific scenarios.
  • You can avoid complex queries (e.g. joins in SQL) which makes the reads more performant.
  • Keeping the command and the read models in sync can become complex.
  • Applications that expect a high amount of reads
  • Applications with complex domains

4. The Event Sourcing Architectural Pattern

As I mentioned above, CQRS often goes hand in hand with event sourcing. This is a pattern where you don’t store the current state of your model in the database, but rather the events that happened to the model. So when the name of a customer changes, you won’t store the value in a “Name” column. You will store a “NameChanged” event with the new value (and possibly the old one too).

When you need to retrieve a model, you retrieve all its stored events and reapply them on a new object. We call this rehydrating an object.

A real-life analogy of event sourcing is accounting. When you add an expense, you don’t change the value of the total. In accounting, a new line is added with the operation to be performed.

If an error was made, you simply add a new line. To make your life easier, you could calculate the total every time you add a line. This total can be regarded as the read model. The example below should make it more clear.

presentation layer ui

You can see that we made an error when adding Invoice 201805. Instead of changing the line, we added two new lines: first, one to cancel the wrong line, then a new and correct line.

This is how event sourcing works. You never remove events, because they have undeniably happened in the past. To correct situations, we add new events.

Also, note how we have a cell with the total value. This is simply a sum of all values in the cells above. In Excel, it automatically updates so you could say it synchronizes with the other cells. It is the read model, providing an easy view for the user.

Event sourcing is often combined with CQRS because rehydrating an object can have a performance impact, especially when there are a lot of events for the instance. A fast read model can significantly improve the response time of the application.

  • This software architecture pattern can provide an audit log out of the box. Each event represents a manipulation of the data at a certain point in time.
  • It requires some discipline because you can’t just fix wrong data with a simple edit in the database.
  • It’s not a trivial task to change the structure of an event. For example, if you add a property, the database still contains events without that data. Your code will need to handle this missing data graciously.

Ideal for Applications That:

  •  Need to publish events to external systems
  • Will be built with CQRS
  • Have complex domains
  • Need an audit log of changes to the data

5. The Microservices Architectural Pattern

When you write your application as a set of microservices, you’re actually writing multiple applications that will work together. Each microservice has its own distinct responsibility and teams can develop them independently of other microservices.

The only dependency between them is the communication. As microservices communicate with each other, you will have to make sure messages sent between them remain backwards compatible. This requires some coordination, especially when different teams are responsible for different microservices.

A diagram can explain.

presentation layer ui

You can imagine this is an application where the user can order something. The separate microservices can call each other too. For example, the payment service may notify the orders service when a payment succeeds. The orders service could then call the inventory service to adjust the stock.

There is no clear rule of how big a microservice can be. In the previous example, the user profile service may be responsible for data like the username and password of a user, but also the home address, avatar image, favorites, etc. It could also be an option to split all those responsibilities into even smaller microservices.

  • You can write, maintain, and deploy each microservice separately.
  • A microservices architecture should be easier to scale, as you can scale only the microservices that need to be scaled. There’s no need to scale the less frequently used pieces of the application.
  • It’s easier to rewrite pieces of the application because they’re smaller and less coupled to other parts.
  • Contrary to what you might expect, it’s actually easier to write a well-structured monolith at first and split it up into microservices later. With microservices, a lot of extra concerns come into play: communication, coordination, backward compatibility, logging, etc. Teams that miss the necessary skill to write a well-structured monolith will probably have a hard time writing a good set of microservices.
  • A single action of a user can pass through multiple microservices. There are more points of failure, and when something does go wrong, it can take more time to pinpoint the problem.
  • Applications where certain parts will be used intensively and need to be scaled
  • Services that provide functionality to several other applications
  • Applications that would become very complex if combined into one monolith
  • Applications where clear bounded contexts can be defined

I’ve explained several software architecture patterns, as well as their advantages and disadvantages. But there are more patterns than the ones I’ve laid out here. It is also not uncommon to combine several of these patterns.

They aren’t always mutually exclusive. For example, you could have several microservices and have some of them use the layered pattern, while others use CQRS and event sourcing.

The important thing to remember is that there isn’t one solution that works everywhere. When we ask the question of which pattern to use for an application, the age-old answer still applies: “it depends.”

You should weigh in on the pros and cons of a solution and make a well-informed decision.

Make your .NET code beautiful with NDepend

Download the NDepend Trial and gain valuable insights into your .NET code within a few minutes

  • Pingback: Software Architecture: the 5 Patterns You Need to Know – NDepend – Bitbucket Bits

Nice article, Peter! These are great essentials that every developer should know about.

I like the clear structure of the article. What I’m missing is a suggestion on the architecture of the services of a microservice architecture.

could be added in this list the architecture of ports and adapters, the clean architecture or the onion

Simply fantastic with real-time examples

Comments are closed.

  • Network infrastructure

presentation layer

Andrew Froehlich

  • Andrew Froehlich, West Gate Networks

What is the presentation layer?

The presentation layer resides at Layer 6 of the Open Systems Interconnection ( OSI ) communications model and ensures that communications that pass through it are in the appropriate form for the recipient application. In other words, the presentation layer presents the data in a readable format from an application layer perspective.

For example, a presentation layer program could format a file transfer request in binary code to ensure a successful file transfer . Because binary is the most rudimentary of computing languages, it ensures that the receiving device can decipher and translate it into a format the application layer understands and expects.

How the presentation layer works

Once the application layer passes data meant for transport to another device in a certain format, the presentation layer then prepares this data in the most appropriate format the receiving application can understand.

Common data formats include the following:

  • American Standard Code for Information Interchange and Extended Binary Coded Decimal Interchange Code for text;
  • JPEG , GIF and TIFF for images; and
  • MPEG, MIDI and QuickTime for video.

Encryption and decryption of data communications are also performed at the presentation layer. Here, encryption methods and keys exchange between the two communicating devices. Only the sender and receiver can properly encode and decode data so it returns to a readable format.

The presentation layer can serialize -- or translate -- more complex application data objects into a storable and transportable format. This helps to rebuild the object once it arrives at the other side of the communications stream. The presentation layer also deserializes the data stream and places it back into an object format that the application can understand by the application.

Chart depicting the location of the presentation layer within the OSI model.

The tool that manages Hypertext Transfer Protocol ( HTTP ) is an example of a program that loosely adheres to the presentation layer of OSI.

Although it's technically considered an application-layer protocol per the TCP/IP model , HTTP includes presentation layer services within it. HTTP works when the requesting device forwards user requests passed to the web browser onto a web server elsewhere in the network.

HTTP receives a return message from the web server that includes a Multipurpose Internet Mail Extensions ( MIME ) header. The MIME header indicates the type of file -- text, video, or audio -- that has been received so that an appropriate player utility can present the file to the user.

Functions of the presentation layer

  • ensures proper formatting and delivery to and from the application layer;
  • performs data encryption; and
  • manages serialization of data objects.

Editor's note: This article was republished in January 2023 to improve the reader experience.

Continue Reading About presentation layer

  • What is the difference between TCP/IP model vs. OSI model?
  • Data and file formatting

Related Terms

Dig deeper on network infrastructure.

presentation layer ui

What are the most important email security protocols?

PeterLoshin

file extension (file format)

RobertSheldon

network protocol

KinzaYasar

MIME (Multipurpose Internet Mail Extensions)

RahulAwati

Organizations have ramped up their use of communications platform as a service and APIs to expand communication channels between ...

Google will roll out new GenAI in Gmail and Docs first and then other apps throughout the year. In 2025, Google plans to ...

For successful hybrid meeting collaboration, businesses need to empower remote and on-site employees with a full suite of ...

Mobile devices bring their own set of challenges and risks to enterprise security. To handle mobile-specific threats, IT should ...

Android Enterprise can simplify Android management, but the wrong device enrollment method can complicate IT's job. Understand ...

QR codes are a convenient tool for Android Enterprise enrollment, but this method has some drawbacks. Discover the factors ...

You can issue commands through your Linux CLI to gather CPU information, including detailed information on cores, class, ...

Blockchain is most famous for its cryptocurrency applications, but data centers can employ it for a variety of business-related ...

In this Q&A, JetCool's CEO talks about the growing interest in liquid cooling and how it's being used to divert heat away from ...

Global IT consultancies take a multilayered approach to GenAI training by developing in-house programs, partnering with tech ...

IT service providers are upskilling a large portion of their workforces on the emerging technology. The campaign seeks to boost ...

Early-stage companies featured at MIT Sloan's annual CIO event tap partners to speed up technology deployment and broaden their ...

Presentation Domain Data Layering

26 August 2015

Martin Fowler

team organization

encapsulation

application architecture

web development

One of the most common ways to modularize an information-rich program is to separate it into three broad layers: presentation (UI), domain logic (aka business logic), and data access. So you often see web applications divided into a web layer that knows about handling HTTP requests and rendering HTML, a business logic layer that contains validations and calculations, and a data access layer that sorts out how to manage persistent data in a database or remote services.

On the whole I've found this to be an effective form of modularization for many applications and one that I regularly use and encourage. It's biggest advantage (for me) is that it allows me to reduce the scope of my attention by allowing me to think about the three topics relatively independently. When I'm working on domain logic code I can mostly ignore the UI and treat any interaction with data sources as an abstract set of functions that give me the data I need and update it as I wish. When I'm working on the data access layer I focus on the details of wrangling the data into the form required by my interface. When I'm working on the presentation I can focus on the UI behavior, treating any data to display or update as magically appearing by function calls. By separating these elements I narrow the scope of my thinking in each piece, which makes it easier for me to follow what I need to do.

This narrowing of scope doesn't imply any sequence to programming them - I usually find I need to iterate between the layers. I might build the data and domain layers off my initial understanding of the UX, but when refining the UX I need to change the domain which necessitates a change to the data layer. But even with that kind of cross-layer iteration, I find it easier to focus on one layer at a time as I make changes. It's similar to the switching of thinking modes you get with refactoring's two hats .

Another reason to modularize is to allow me to substitute different implementations of modules. This separation allows me to build multiple presentations on top of the same domain logic without duplicating it. Multiple presentations could be separate pages in a web app, having a web app plus mobile native apps, an API for scripting purposes, or even an old fashioned command line interface. Modularizing the data source allows me to cope gracefully with a change in database technology, or to support services for persistence that may change with little notice. However I have to mention that while I often hear about data access substitution being a driver for separating the data source layer, I rarely hear of someone actually doing it.

Modularity also supports testability, which naturally appeals to me as a big fan of SelfTestingCode . Module boundaries expose seams that are good affordance for testing . UI code is often tricky to test, so it's good to get as much logic as you can into a domain layer which is easily tested without having to do gymnastics to access the program through a UI 1 . Data access is often slow and awkward, so using TestDoubles around the data layer often makes domain logic testing much easier and responsive.

1: A PageObject is also an important tool to help testing around UIs.

While substitutability and testability are certainly benefits of this layering, I must stress that even without either of these reasons I would still divide into layers like this. The reduced scope of attention reason is sufficient on its own.

When talking about this we can either look at it as one pattern (presentation-domain-data) or split it into two patterns (presentation-domain, and domain-data). Both points of view are useful - I think of presentation-domain-data as a composite of presentation-domain and domain-data.

I consider these layers to be a form of module, which is a generic word I use for how we clump our software into relatively independent pieces. Exactly how this corresponds to code depends on the programming environment we're in. Usually the lowest level is some form of subroutine or function. An object-oriented language will have a notion of class that collects functions and data structure. Most languages have some form of higher level called packages or namespaces, which often can be formed into a hierarchy. Modules may correspond to separately deployable units: libraries, or services, but they don't have to.

Layering can occur at any of these levels. A small program may just put separate functions for the layers into different files. A larger system may have layers corresponding to namespaces with many classes in each.

I've mentioned three layers here, but it's common to see architectures with more than three layers. A common variation is to put a service layer between the domain and presentation, or to split the presentation layer into separate layers with something like Presentation Model . I don't find that more layers breaks the essential pattern, since the core separations still remain.

The dependencies generally run from top to bottom through the layer stack: presentation depends on the domain, which then depends on the data source. A common variation is to arrange things so that the domain does not depend on its data sources by introducing a mapper between the domain and data source layers. This approach is often referred to as a Hexagonal Architecture .

These layers are logical layers not physical tiers. I can run all three layers on my laptop, I can run the presentation and domain model in a desktop with a database on a server, I can split the presentation with a rich client in the browser and a Backed For Frontend on the server. In that case I treat the BFF as a presentation layer as it's focused on supporting a particular presentation option.

Although presentation-domain-data separation is a common approach, it should only be applied at a relatively small granularity. As an application grows, each layer can get sufficiently complex on its own that you need to modularize further. When this happens it's usually not best to use presentation-domain-data as the higher level of modules. Often frameworks encourage you to have something like view-model-data as the top level namespaces; that's OK for smaller systems, but once any of these layers gets too big you should split your top level into domain oriented modules which are internally layered.

Developers don't have to be full-stack but teams should be.

One common way I've seen this layering lead organizations astray is the AntiPattern of separating development teams by these layers. This looks appealing because front-end and back-end development require different frameworks (or even languages) making it easy for developers to specialize in one or the other. Putting those people with common skills together supports skill sharing and allows the organization to treat the team as a provider of a single, well-delineated type of work. In the same way, putting all the database specialists together fits in with the common centralization of databases and schemas. But the rich interplay between these layers necessitates frequent swapping between them. This isn't too hard when you have specialists in the same team who can casually collaborate, but team boundaries add considerable friction, as well as reducing an individual's motivation to develop the important cross-layer understanding of a system. Worse, separating the layers into teams adds distance between developers and users. Developers don't have to be full-stack (although that is laudable) but teams should be.

Further Reading

I've written about this separation from a number of different angles elsewhere. This layering drives the structure of P of EAA and chapter 1 of that book talks more about this layering. I didn't make this layering a pattern in its own right in that book but have toyed with that territory with Separated Presentation and PresentationDomainSeparation .

For more on why presentation-domain-data shouldn't be the highest level modules in a larger system, take a look at the writing and speaking of Simon Brown . I also agree with him that software architecture should be embedded in code.

I had a fascinating discussion with my colleague Badri Janakiraman about the nature of hexagonal architectures. The context was mostly around applications using Ruby on Rails, but much of the thinking applies to other cases when you may be considering this approach.

Acknowledgements

Stack Exchange Network

Stack Exchange network consists of 183 Q&A communities including Stack Overflow , the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Presentation VS Application layer in DDD

I have trouble drawing a clear line between Presentation and Application layer in Domain Driven Design.

Where should Controllers, Views, Layouts, Javascript and CSS files go?

Is it in the Application or the Presentation layer?

And if they go all together in the same layer, what contains the other one? Is it empty?

  • architecture
  • domain-driven-design

Matthieu Napoli's user avatar

3 Answers 3

Just because someone created and named "Application Layer" and "Presentation Layer" doesn't mean your application should have them. You should create layers AFTER you created substantial amount of code which you grouped together and want to name this group for sake of communication between developers and clarity of code.

From point of DDD. Application Layer is everything that is not Domain layer. Which includes application logic, presentation and application services.

Euphoric's user avatar

  • 3 Thank you, indeed you made me realize that for my case separating Application and Presentation is useless. Simplicity first! –  Matthieu Napoli Commented Dec 24, 2012 at 9:43
  • If DDD has REST API instead of UI in presentation layer, would REST API be an application or presentation layer. I am now confused, since I was sure that REST API is a presentation layer.. –  Dario Granich Commented May 6, 2016 at 13:33
  • 15 Actually, DDD prescribes four layers in the following order, from higher to lower: Presentation, Application, Domain, Infrastructure. So, the Application layer does not include "presentation". Also, it's always a good idea to decide on the layers before a significant amount of code is written, as it isn't only about grouping code together but also about constraining the direction of compile-time dependencies. –  Rogério Commented Feb 21, 2017 at 17:36

There is a big difference between the application layer and the presentation layer from a DDD view point.

Although DDD centers around how to model the domain using the DDD building blocks and concepts such as bounded contexts, Ubiquitous language and so, it is still vital to clearly identify and separate the various layers in your app.

The architecture plays a big role in implementing a successful DDD app. A famous architecture that gained a lot of hype lately is the onion architecture:

enter image description here

In this design the UI/Presentation layer and the application layer are clearly separated. Merging the 2 together introduces tight coupling between 2 layers that have clear separate concerns and responsibilities.

The Presentation layer should only house presentation logic. Avoid Smart UIs that know too much. This mainly houses the MVC's Controllers and views in addition to CSS, JS, templates, forms and everything that relates to response and request objects.

The actions issued through presentation are delegated to the application layer through commands. The application layer contains the application logic. It normally maps to a use case. It contains WHAT the system should do to satisfy a use case. A typical application service will ask a repository to return an aggregate then invoke an action on that aggregate.

Have a look at the sample project from Vaughn Vernon's IDDD

Songo's user avatar

  • 2 +1. This is how i've implemented my project. Immediately, i was able to make gains by doing so. Since I abstracted to an application layer, I was able to have multiple presentation layers. For example, our web api and our web site both consume the application layer which saved a lot of time and duplicated code since my web app doesn't have to frame messaging to and from the web api and it keeps all of the logic in sync between the two. –  Sinaesthetic Commented Jan 21, 2016 at 1:47
  • Where are entry point and composition root placed? I always thought it was a responsibility of Application layer. But now it looks like this is Presentation layer. –  Denis535 Commented Feb 24, 2020 at 22:00

Domain Driven Design has nothing to do with either Presentation layer or Application layer. DDD is a methodology whose main focus is on the Domain layer. That is, DDD does not impose any constraints regarding any other layer except for the Domain layer and Your question as well could be asked in the context of any other methodology.

That being said, it's very common to use a four-layer architecture for DDD applications. Here's an example of one such application showing the layers and their intended use: DDDSample Architecture . So, if you choose to use this architecture your views and layouts would go to the Interfaces layer and the controllers, if interface-independent, would go to the Application layer.

You might as well choose any other kind of architecture, as I've said DDD does not impose constraints. There are many MVC frameworks out there that have different structures and yet could also be used for DDD applications. Then, of course, you would place Your views and layouts accordingly.

gnat's user avatar

Your Answer

Reminder: Answers generated by artificial intelligence tools are not allowed on Software Engineering Stack Exchange. Learn more

Sign up or log in

Post as a guest.

Required, but never shown

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy .

Not the answer you're looking for? Browse other questions tagged architecture domain-driven-design layers or ask your own question .

  • The Overflow Blog
  • The framework helping devs build LLM apps
  • How to bridge the gap between Web2 skills and Web3 workflows
  • Featured on Meta
  • Upcoming initiatives on Stack Overflow and across the Stack Exchange network...
  • Announcing a change to the data-dump process

Hot Network Questions

  • Galilean invariance of the wave equation
  • What's that little animation between Avatar: The Last Airbender Book 2 and Book 3?
  • What is the function of this resistor and capacitor at the input of optoisolator?
  • Are the hangers on these joists sized and installed properly?
  • Can perfectly stable orbits exist in GR?
  • Do we always use "worsen" with something which is already bad?
  • What kind of pressures would make a culture force its members to always wear power armour
  • Is "farfel" an idiolectical quirk/part of a familect?
  • Setting position of PlotLegends affect position of PlotLabel
  • replacing a 15-amp breaker with a 20-amp breaker
  • When Trump ex-rivals, who previously gave Trump terrible comments, now turn to praising him, what benefits could they gain?
  • How to move the color blocks into the red frame region marked?
  • Is it worth it to apply to jobs that have over 100 applicants or have been posted for few days?
  • Left crank arm misaligned on climb
  • Swap the positions of the 4 chess knights
  • Selecting unsymbolised features in QGIS
  • What is the meaning of the "Super 8 - Interactive Teaser" under "EXTRAS" in Portal 2?
  • Old client wants files from materials created for them 6 years ago
  • How to save oneself from this particular angst?
  • Chemical Coin Flipping as Divination
  • Did Arab Christians use the word "Allah" before Islam?
  • Always orient a sundial towards polar north?
  • Reducing required length of a mass driver using loop?
  • Accelerating semidecision of halting problem

presentation layer ui

  • Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers
  • Advertising & Talent Reach devs & technologists worldwide about your product, service or employer brand
  • OverflowAI GenAI features for Teams
  • OverflowAPI Train & fine-tune LLMs
  • Labs The future of collective knowledge sharing
  • About the company Visit the blog

Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Get early access and see previews of new features.

Presentation layer / Public Services layer. A common term?

While defining our application architecture (which contains both web UI and external web services) we stumbled upon our inability to find a common name for the topmost layer. It is quite clear that there are DAL (data access layer) and BLL (business logic layer) in our application. On the top of BLL, there reside the UI, which is commonly called the presentation layer (e.g., http://msdn.microsoft.com/en-us/library/ff647339.aspx ). But there's also a service layer, which resides on the top of BLL as well!

But a cake can't have two layers on the same level :) So please help me to find a term for that.

  • architecture
  • nomenclature
  • presentation-layer
  • service-layer

Jonathan Day's user avatar

3 Answers 3

The term API (Application Programming Interface) is commonly used for programming interfaces, though in this case "Service Layer" may be more appropriate and descriptive.

Layers can be side by side - nothing says they have to be one on top of another.

Oded's user avatar

  • API and "Service Layer" can be terms for web services. But what about the UI part? I'd like to have a common term. And in my world layers have to be on the top of each other. Service layer and web presentation are in one layer, at least in my opinion. –  Dmytro Shevchenko Commented Sep 1, 2010 at 14:58
  • @Shedal - If you can see it and interact with it, it belongs to the Presentation Layer. –  Oded Commented Sep 1, 2010 at 15:01

Presentation Layer is the one I've heard most for the layer containing UI components.

  • Yes, but what about a common term for Ui and services? –  Dmytro Shevchenko Commented Sep 1, 2010 at 14:56

What about Outer Layer? Top Layer? The Layer-that-shall-not-be-named?

ObiWanKenobi's user avatar

Your Answer

Reminder: Answers generated by artificial intelligence tools are not allowed on Stack Overflow. Learn more

Sign up or log in

Post as a guest.

Required, but never shown

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy .

Not the answer you're looking for? Browse other questions tagged architecture layer nomenclature presentation-layer service-layer or ask your own question .

  • The Overflow Blog
  • The framework helping devs build LLM apps
  • How to bridge the gap between Web2 skills and Web3 workflows
  • Featured on Meta
  • Upcoming initiatives on Stack Overflow and across the Stack Exchange network...
  • Announcing a change to the data-dump process
  • What makes a homepage useful for logged-in users

Hot Network Questions

  • Unchained rogue damage output
  • Does the question "will I get transplanted" make sense to your ears?
  • How to fix the CrowdStrike blue screen?
  • How can I connect my thick wires into an ikea wire connector
  • What is the meaning of the "Super 8 - Interactive Teaser" under "EXTRAS" in Portal 2?
  • Teaching students how to check the validity of their proofs
  • Unused Private Pension fund transfer to offspring
  • Since what year would small-scale cheating have given an advantage in e.g. the World Championship?
  • Wait, ASCII was 128 characters all along?
  • 2018 movie where everyone has chips in their brains and a cop used the chip to see what a suspect could see
  • Is it worth it to apply to jobs that have over 100 applicants or have been posted for few days?
  • Diminished/Half diminished
  • How much coolant drip is normal on old car without overflow tank
  • Maximum of coefficients of a quadratic equation
  • How to receive large files guaranteeing authenticity, integrity and sending time
  • Why don't we call value investing "timing the market"?
  • Does the grammar underlying 为期 generalize to 为主, 为基础, and so on?
  • What's that little animation between Avatar: The Last Airbender Book 2 and Book 3?
  • Can we view higher homotopy groups as symmetries?
  • When Trump ex-rivals, who previously gave Trump terrible comments, now turn to praising him, what benefits could they gain?
  • Is it fair to say truth is used more in logic than in math? If so, what are the reasons for doing so?
  • Rudimentary black jack game implementation
  • How to move the color blocks into the red frame region marked?
  • How to access specific entry from list of arguments, when index is provided as a letter?

presentation layer ui

IMAGES

  1. Free Modern Dashboard UI & Presentation Template (XD & PSD)

    presentation layer ui

  2. Flutter App Architecture: The Presentation Layer

    presentation layer ui

  3. Free Behance UI UX Presentation Template XD

    presentation layer ui

  4. Service-centric architecture with multiple presentation layers (user

    presentation layer ui

  5. Behance UI UX Presentation Template V1 on Behance

    presentation layer ui

  6. Elements of ui design. Modern presentation with infographic, 3261625

    presentation layer ui

VIDEO

  1. Design issues in network layer|Services provided by network layer to transport layer

  2. OSI Model Layer 1 Physical

  3. What is Serverless Computing

  4. Graphics design

  5. Application layer Presentation layer

  6. 78) Better DataReader in a Multi-Tiered Solution

COMMENTS

  1. Difference between presentation layer and user-interface

    0. The presentation layer delivers information to the application layer for display. The presentation layer, in some cases, handles data translation to allow use on a particular system. The user interface shows you the data once the presentation layer has done any translations it needs to.

  2. UI layer

    Because the role of the data layer is to hold, manage, and provide access to the app data, the UI layer must perform the following steps: Consume app data and transform it into data the UI can easily render. Consume UI-renderable data and transform it into UI elements for presentation to the user. Consume user input events from those assembled ...

  3. App Architecture: Presentation layer

    Model. The Presentation layer also has its data models that reflect models from the Domain layer but are more UI-specific. The mapping logic of the presentation model to the domain and vice versa should be placed in the ViewModel class. The presentation layer shouldn't expose the UI model to other layers.

  4. Clean Architecture Guide (with tested examples): Data Flow ...

    Clean Architecture Layers. Let's identify the different layers & boundaries. Presentation Layer contains UI (Activities & Fragments) that are coordinated by Presenters/ViewModels which execute 1 or multiple Use cases. Presentation Layer depends on Domain Layer. Domain Layer is the most INNER part of the onion (no dependencies with other layers) and it contains Entities, Use cases ...

  5. Presentation Layer in OSI model

    Prerequisite : OSI Model. Introduction : Presentation Layer is the 6th layer in the Open System Interconnection (OSI) model. This layer is also known as Translation layer, as this layer serves as a data translator for the network. The data which this layer receives from the Application Layer is extracted and manipulated here as per the required ...

  6. Chapter 10

    The presentation layer contains the components that implement and display the user interface and manage user interaction. This layer includes controls for user input and display, in addition to components that organize user interaction. Figure 1 shows how the presentation layer fits into a common application architecture.

  7. Multitier architecture

    Presentation layer (a.k.a. UI layer, view layer, presentation tier in multitier architecture) ... the presenter sublayer might be used as an additional layer between the user interface layer and the business/application layer (as represented by the model sublayer). [citation needed]

  8. Android App Architecture [Part 4] Presentation Layer

    As the name suggests, this layer is responsible for presenting UI to the user. It's used to perform necessary UI logic based on the data received through the domain layer and user interactions. In ...

  9. App Architecture: Presentation layer

    The Presentation layer also has its data models that reflect models from the Domain layer but are more UI-specific. The mapping logic of the presentation model to the domain and vice versa should be placed in the ViewModel class. The presentation layer shouldn't expose the UI model to other layers.

  10. Presentation Layer

    The presentation layer is the lowest layer at which application programmers consider data structure and presentation, instead of simply sending data in the form of datagrams or packets between hosts. This layer deals with issues of string representation - whether they use the Pascal method (an integer length field followed by the specified ...

  11. Presentation layer

    The presentation layer ensures the information that the application layer of one system sends out is readable by the application layer of another system. On the sending system it is responsible for conversion to standard, transmittable formats. [7] On the receiving system it is responsible for the translation, formatting, and delivery of ...

  12. Angular Architecture

    Presentation layer The presentation layer (UI) layer is where all Angular components reside. Its primary responsibility is to present the application's UI and delegate user actions to the core layer through the abstraction layer. Inside of presentation layer we have: Smart/container components: can pass data down to dumb components

  13. Web Application Architecture: How the Web Works

    The presentation layer is accessible to users via a browser and consists of user interface components and UI process components that support interaction with the system. It's developed using three core technologies: HTML, CSS, and JavaScript. While HTML is the code that determines what your website will contain, CSS controls how it will look.

  14. 1. Layered Architecture

    Each layer of the layered architecture pattern has a specific role and responsibility within the application. For example, a presentation layer would be responsible for handling all user interface and browser communication logic, whereas a business layer would be responsible for executing specific business rules associated with the request.

  15. Software Architecture: The 5 Patterns You Need to Know

    Presentation or UI layer; Application layer; Business or domain layer; Persistence or data access layer; Database layer; The idea is that the user initiates a piece of code in the presentation layer by performing some action (e.g. clicking a button). The presentation layer then calls the underlying layer, i.e. the application layer.

  16. What is presentation layer?

    The presentation layer is located at Layer 6 of the OSI model. The tool that manages Hypertext Transfer Protocol ( HTTP) is an example of a program that loosely adheres to the presentation layer of OSI. Although it's technically considered an application-layer protocol per the TCP/IP model, HTTP includes presentation layer services within it.

  17. Presentation Domain Data Layering

    One of the most common ways to modularize an information-rich program is to separate it into three broad layers: presentation (UI), domain logic (aka business logic), and data access. So you often see web applications divided into a web layer that knows about handling HTTP requests and rendering HTML, a business logic layer that contains ...

  18. architecture

    In this design the UI/Presentation layer and the application layer are clearly separated. Merging the 2 together introduces tight coupling between 2 layers that have clear separate concerns and responsibilities. The Presentation layer should only house presentation logic. Avoid Smart UIs that know too much.

  19. Presentation layer / Public Services layer. A common term?

    The term API (Application Programming Interface) is commonly used for programming interfaces, though in this case "Service Layer" may be more appropriate and descriptive. Layers can be side by side - nothing says they have to be one on top of another. API and "Service Layer" can be terms for web services.