Home > Articles > Web Development > ASP.NET

This chapter is from the book

The Model-View-ViewModel Pattern

In 2005, a developer named John Gossman working on WPF—which at the time was code-named Avalon—published a blog post that would ultimately introduce the MVVM pattern to the world (http://blogs.msdn.com/b/johngossman/archive/2005/10/08/478683.aspx). In his post he described “a variation of Model/View/Controller (MVC) that is tailored for modern UI development platforms where the View is the responsibility of a designer rather than a classic developer.”

The introduction to his post provides valuable insight into one of the original motivations for the pattern: the designer/developer workflow. His post further explains that the view is defined declaratively (a reference to Xaml) and is responsible for inputs, keyboard shortcuts, visual elements, and more. The view model is responsible for tasks that are too specific for the general model to handle (such as complex UI operations), for maintaining the view state, and for projecting the model to the view, especially when the model contains data types that won’t map directly to controls.

Although MVVM is most often compared to MVC, it actually makes more sense to think of it as a specialized flavor of MVP that uses data-binding and the Visual State Manager (VSM). Instead of raising events, the view drives the view model through data-binding—whether it is by updating a value that in turn synchronizes to a property on the view model, or by mapping an event to a command that fires on the view model. The input aspects of the controller have been absorbed into the view, while the presentation logic is distributed between the view model and the view. Presentation logic in the view takes the form of behaviors, triggers, visual states, and value converters.

Like other patterns, MVVM is a solution to common problems. When implemented correctly, it should make the job of building a Silverlight application easier. Unfortunately, the pattern can be abused and end up slowing down projects and making them more complex than necessary. I’ve built dozens of large enterprise Silverlight applications. Not all applications followed the MVVM pattern, and in many cases my company was called in to rescue a failing project by refactoring the application to use MVVM. Although the pattern is now over six years old, there are many lingering misconceptions. Table 7.1 lists some of these misconceptions and the truth that addresses them.

Table 7.1. Common MVVM Misconceptions

Misconception

Truth

MVVM is extremely complex.

MVVM can be incredibly simple when implemented correctly.

Code-behind isn’t allowed in MVVM.

Code-behind is simply an extension of the declarative Xaml for the view. The view is responsible for managing the user interface, including user inputs, and there is no reason the code-behind cannot deal with events and interactions.

MVVM is hard to your implement.

Many frameworks exist that can enable you to have project up and running in minutes. I recorded a video to demonstrate building a feed reader from scratch using MVVM in just 30 minutes (http://vimeo.com/17926625).

MVVM eliminates the need for value converters.

Value converters are reusable, testable pieces of code that can map data from the model to the view, and there is no reason to eliminate them when using the MVVM pattern.

MVVM reduces the performance of the application.

The improper implementation of any pattern can create performance issues. Proper use of MVVM facilitates unit tests that can help tweak and improve performance.

MVVM is only good for very large projects.

A good MVVM framework coupled with solid understanding is just as suitable for small projects as it is big ones.

MVVM is about commands and messaging systems.

MVVM simply specifies the responsibilities of various modules within the code. Commands, messaging frameworks, and other constructs are just helpers and building blocks.

MVVM is hard to understand.

MVVM is no more difficult to understand than data-binding and the Visual State Manager, because it really is just a pattern that describes how best to use these features.

In the rest of this chapter you’ll learn about the various parts of MVVM and how to apply it. If you’ve read the previous chapters in this book and followed the examples, you already have an understanding of MVVM because you’ve created specific classes that implement property-change notification to facilitate data-binding. Those classes can actually be thought of as your view models.

Contrary to the misconceptions about MVVM, there are many advantages the pattern provides above and beyond the separation of design from development. In my experience, these are the top ten benefits you may receive by using MVVM in your applications:

  1. A clean separation of concerns (decoupling)—MVVM follows best practices for software architecture.
  2. Designer/developer workflow—MVVM enables parallel development and design by multiple team members working on the same project.
  3. Unit testing—You will learn more about testing in Chapter 9, “Testing.”
  4. Use of data-binding—MVVM takes direct advantage of the rich and powerful data-binding system in Silverlight.
  5. Improved code reuse—View models can be used to power multiple views, and various helpers and scaffolding can be reused throughout your project and across various products in your organization.
  6. Modularity—MVVM encourages a modular design that makes it easy to modify parts of the application independently of each other.
  7. Refactoring containment—Through the clean separation of concerns, MVVM minimizes the impact to other areas of the application from refactoring.
  8. Extensibility—A well-designed MVVM framework makes it easy to extend the application by adding new screens, modules, and plug-ins.
  9. Tools support—Various tools, such as Expression Blend and the designer, are built in to Visual Studio that can take direct advantage of MVVM.
  10. Pattern vocabulary

The final item, pattern vocabulary, requires some additional explanation. When you are learning how to read, there is a strong correlation between the size of your vocabulary and your ability to comprehend what you are reading. This should not be surprising because vocabulary provides the building blocks for the text you are trying to comprehend, and not understanding those blocks can lead to confusing conclusions and misinterpretations of the text. Although there is a strong correlation, vocabulary certainly doesn’t guarantee comprehension because you must be able to piece the words together and derive their meaning as a whole.

Developing software is an exercise that also involves a vocabulary. You start with the vocabulary of the language you are developing in. Programs have their own syntax and grammar, and comprehension relies on your ability to interpret the keywords correctly and understand them in context. Patterns provide a higher level vocabulary that can describe entire subroutines and components within the system. As with vocabulary, knowing a pattern isn’t the same thing as comprehending how it best fits into a software application (or whether it belongs at all).

The more you are able to understand and integrate patterns, the more you will be able to build your vocabulary and better comprehend complex software systems. Although I am not aware of any scientific studies that definitively support this conclusion, it is based on years of working in the software industry with individuals of varying degrees of skill and experience. I’ve found the developers who are involved in the most successful projects and who have tackled the most complex systems also tend to have a strong pattern vocabulary. They are not only aware of many patterns that exist in software development, but also understand when and where they make sense.

I believe MVVM is popular because it has been so successful at providing the benefits listed earlier when implemented correctly. MVVM is an important pattern to learn and understand for Silverlight LOB applications—even if only to articulate why it doesn’t make sense for a particular project. Like all patterns, it is a tool and must be used for the right job. In the next few sections I’ll cover MVVM in more detail to help you learn the pattern and determine when it makes sense to use it in your applications. I’ll start by examining the components that make up MVVM.

The Model

The model is often confused with a “data model,” which is far too specific. A better definition is the application’s model of the world. It is the model that encompasses everything that must happen in order to solve the business problem without defining a specific user interface or presentation of data. Some like to call this the domain model, but a domain model is a conceptual representation, whereas the model in MVVM is an actual implementation.

To provide a simple example, a banking system might contain customers and accounts. The representations of customers and accounts are part of the model. The model describes how they are related: A customer has one or many accounts. It describes state (an account is open or closed) and provides behaviors (an account accrues interest). To make the model work requires implementations of classes with properties, a database to store the information, and loads of APIs to fetch data, transfer it, and apply various algorithms.

When built correctly, the model should expose only the parts needed by the application. For example, the presentation layer shouldn’t have to worry about how the data is stored (is it in a database or in an XML file?) or how the data is retrieved (was it parsed and passed as a binary object over a TCP/IP socket or sent over a REST service?). A model that is too open will create unnecessary dependencies and overcomplicate the code.

Regardless of whether you are a junior developer learning how to build applications or a seasoned architect who has worked on massive enterprise software projects, I believe it is important to know some key fundamentals of software design. As I stated before, I can’t point to a scientific study that states you must follow these principles to build quality software, but I can certainly point to my experience that developers who follow these principles tend to write code that ships with fewer defects, is easier to understand, can be readily maintained, and is produced more quickly than code written by developers who ignore them. These principles will assist you with building the model portion of your MVVM application correctly.

Don’t Repeat Yourself

The first principle to follow is called D.R.Y., which stands for Don’t Repeat Yourself. This is an easy principle to follow. As you are writing your software, you will find there are certain blocks of code and algorithms that repeat themselves. An experienced developer is able to quickly identify those patterns and refactor them into a single class or method. Not only does this save time by not repeating the pattern over and over, it also places the pattern in a single location to make it easier to change the algorithm when it becomes necessary. Finally, it protects other developers by giving them less opportunity to write bad code—it’s a lot easier to introduce bugs in a ten-line block of code than it is calling a simple API.

I recently came across an example of D.R.Y. for a customer project. I was writing a web service interface and quickly noticed a common pattern. Consider the following method that represents a completed web service call:

private static void ClientGetWidgetCompleted(object sender,
    GetWidgetCompletedEventArgs e)
{
    if (e.Error != null)
    {
        throw e.Error;
    }

    var callback = e.UserState as Action<Widget>;

    if (callback != null)
    {
        callback(e.Result);
    }
}

Now look at a similar method that returns a list of related widget items:

private static void ClientGetWidgetItemsCompleted(object sender,
    GetWidgetItemsCompletedEventArgs e)
{
    if (e.Error != null)
    {
        throw e.Error;
    }

    var callback = e.UserState as Action<IEnumerable<WidgetItem>>;

    if (callback != null)
    {
        callback(e.Result);
    }
}

The second method introduced what is referred to as code smell or the symptom of a deeper problem. In this case, the problem wasn’t a bug or defect with how the application runs, but instead a level of complexity that just isn’t necessary. Each time the method is implemented, the developer must remember to check for an error and throw it, then cast the state to get the callback, and finally invoke the callback. Forgetting just one simple step, such as invoking the callback, could result in application defects—in this case, one that would be hard to find because the code will simply wait for a result that never comes.

By looking at the methods and deciding that I did not want to repeat myself, I was able to create an extension method to simplify things. The method uses generics to abstract the part of the formula that changes—in this case the return type—while implementing the rest of the pattern in a single place.

public static class ServiceExtensions
{
    public static Action<T> GetCallback<T>(
        this AsyncCompletedEventArgs args)
    {
        if (args.Error != null)
        {
            throw args.Error;
        }

        var callback =
            args.UserState as Action<T> ??
            (obj =>
                    {
                        throw new Exception();
                    });

        return callback;
    }
}

Now the previous service calls can be simplified to the following—notice how the code does not repeat the pattern, but instead focuses on the parts that are unique to each method:

private static void ClientGetWidgetCompleted(object sender,
    GetWidgetCompletedEventArgs e)
{
    e.GetCallback<Widget>()(e.Result);
}

private static void ClientGetWidgetItemsCompleted(object sender,
    GetWidgetItemsCompletedEventArgs e)
{
    e.GetCallback<IEnumerable<WidgetItem>>()(e.Result);
}

The pattern here worked for the specific application, but I wouldn’t necessarily build it upfront in every project. There is always the possibility that another project will handle service calls completely differently and not use the same type of mechanism to abstract calls. This brings me to the next principle.

You Aren’t Going to Need It

You Aren’t Going to Need It—or Y.A.G.N.I—is one of the most difficult principles to follow. Some software architects tend to dislike this principle because it keeps them from working on really fun, complex systems by introducing all sorts of frameworks and patterns. Instead, it forces them to design simple, straightforward solutions that are written so cleverly that adding additional features when they are actually needed is not a problem. I’ve watched many systems collapse under the burden of features that were piled on “just in case” and then never used. The understanding of what may be needed often fails to meet the future requirement, and results in having to rip out the initial “guess” and extra refactoring to supply the more appropriate solution.

One example of this is the Enterprise Library, a library of implementations that is released by Microsoft’s own Patterns and Practices Team. I was asked by someone how excited I was when a build of this was released for Silverlight, and this person was surprised when I said I may not use it.

Don’t get me wrong—there are a lot of great features in the library and I’ve used it in many projects. The key, however, is to identify the parts you’ll need and use rather than plugging in the entire system and using only a fraction of it. A really common exercise is to load the Exception Handling Application Block because it allows dynamic configuration of your exception policies. Want to change where they are logged? Great—it handles that for you. Want to write certain exceptions to the database, swallow other exceptions, and write yet a third class to a rolling trace file? Not a problem! It’s a very flexible system.

What often ends up happening is the system is put in place, the configuration files are tinkered with until they are working, and then the application goes to production... and that’s it. The policies are never tweaked, there is no swapping of targets or sources, and often there is not a segregation of exception types. Essentially, a big piece of plumbing is put into place when a simple logging mechanism would have sufficed. It gets worse because then when someone does want to log or trace a certain set of events, they have to wade through reams of configuration to finally get the output they are looking for.

It is a much more straightforward approach to assume you aren’t going to need it, but build the code so that it is easy to add later on. In the case of exceptions, you can always provide a consistent pattern of exception blocks that are processed by a common interface, and start with an implementation that sends them to the event log. If you find a real need to enforce a specific set of policies, you can implement the Exception Handling Application Block in your single class and introduce the policies without having to touch the rest of the application.

Another example of Y.A.G.N.I. is caches. Despite there being no metrics to support it, many developers feel that a cache is needed. I’ve often heard, “We’re moving data, we need a cache.” But usually the overhead of synchronizing the cache for thread safety and applying various cache-expiration policies can make it slower than fetching the data directly from the database! There is no rule of thumb, and you must be prepared to analyze performance and obtain metrics in order to determine if there truly is a benefit.

Following this principle simplifies projects and makes them faster and easier to deliver. The fear many people have is that it will be too complex to rip out the code and replace it when a need is identified down the road, but you can cover those bases as well. As long as you build your code on a “solid” foundation, you’ll find it’s easy to introduce the features you do need when you are certain you really need them. That foundation is the next principle.

The S.O.L.I.D. Principle

I saved this principle for last because it’s the more complex one to learn and really builds on the first two. I also cheated because S.O.L.I.D. is not a single principle, but really a set of five principles that I believe are keys to building quality code. I include them here because I know firsthand the impact of applying them can have on the quality of your code. For MVVM to work well, the model must be done right, and S.O.L.I.D. is the foundation to make that happen.

An entire book could be written (and probably has been) about these principles, so I’ll only briefly introduce them here and hope you will explore them further online. S.O.L.I.D. is an acronym for the following principles:

  • Single Responsibility—A class should be responsible for exactly one thing. A great example is a class that reads and parses a comma-separated text file. This class has more than one responsibility because it both reads the file and parses it. A better strategy would be to provide a class that reads files and a class that parses them. Now you can easily add a class that retrieves the file from a web service and passes it along to the parser, or a class that uses the reader to retrieve configuration information.
  • Open/Closed Principle—A class should be open for extension but closed for modification. A great example is a class that has the responsibility for logging. It is common to provide a simple API that takes a message to log. This is fine until you need to specify different places for messages to go. Now the class has to be opened up to modify it and the API changed to provide routing information. A more robust implementation would be a logger that provides a delegate for the call and allows registration of logging implementations. The class can now be extended by providing different logging mechanisms, and does not have to be opened to modify the behavior.
  • Liskov Substitution Principle—This principle states that you should be able to substitute any class for its base class and have it behave the same way. The classic example of this is a square and a rectangle. If you derive the square from the rectangle and override the properties so that setting the width always sets the height, you can no longer substitute the class for its base class. Casting the square to a rectangle will provide unexpected behavior because with a rectangle, you expect to be able to set different widths and heights. A better design is to create an abstract base rectangle that provides getters and private setters. The rectangle implementation derives from this and makes the setters public, whereas the square derives from the same base class and provides a “length of side” property that sets the width and height at the same time.
  • Interface Segregation Principle—This principle goes hand in hand with single responsibility and states that interfaces should be fine-grained and focused on a specific set of related tasks. An example of this is in the .NET Framework. Most classes have a concept of equality (what makes two classes the same) and comparability (what order the classes are in relation to each other in a list). These concepts are used in different ways at different times. Instead of a single interface for both concepts, the .NET Framework provides the IComparable interface and the IEquatable interface. If you are only concerned with equality, you can cast to IEquatable and deal directly with that simple interface. There is no need to involve any other interfaces that aren’t being used.
  • Dependency Injection/Inversion of Control—This principle goes hand in hand with the single responsibility. When the class is required to create an instance of the logger, it is taking control of that dependency and going beyond its single responsibility. This can lead to issues if you decide to swap to a different logging implementation and have to track down all of the places the old logger was created. Instead, you can simply provide a logging interface that is passed into the class. Now the class no longer has the responsibility of finding the logger; it simply consumes the interface. The dependency for the logger was injected and the control inverted to something else. We’ll discuss this concept in detail in the next chapter, which covers the Managed Extensibility Framework (MEF).

These principles work together to provide a set of guidelines for writing flexible, extensible, testable, and maintainable code. When the model of your application follows these principles, the MVVM pattern can easily connect to the interfaces and classes that are needed without creating dependencies on parts of the system that have nothing to do with presentation logic. The model is the “application model” of the real world, but at some point that model must be presented to the end user. This is done through output, which in the case of Silverlight is a very rich and powerful user interface (UI). The screen that the user is presented with is referred to as the view.

The View

The view in Silverlight is the easiest part to describe—it is what interacts with the user. The view itself is the user interface. The user interface is almost always represented using the declarative Xaml markup. The Xaml participates in the dependency property system, and the view is able to present information to the user as well as respond to user inputs. Table 7.2 shows common parts of the views and their function.

Table 7.2. The View in MVVM

Component

Description

Xaml

Declarative markup to provide layout, controls, and other components that make up a screen

Value converters

Special classes used to transform data to a user element type and back

Data templates

Templates that map data elements to controls

Visual state groups

Named states that impact the properties of various elements to provide a physical state based on the logical states of controls

Storyboards

Animations and transitions

Behaviors

Reusable algorithms that can be applied to various controls

Triggers

Algorithms that can be applied to controls and invoked based on configured events

Code-behind

Extensions of the Xaml markup to perform additional UI-specific tasks

It should be obvious from Table 7.2 that the view is not completely ignorant of presentation logic. Commands map controls to actions on the controller, and data-binding declarations require knowledge of the structure of the underlying data to bind to. Animations, visual states, templates, behaviors, and triggers all represent various components of business logic that relate to the view.

What may not be as obvious is that all of these components are stateless with regard to the model of the application. Storyboards maintain a state (started, stopped, playing, and so on) and visual state groups maintain a state, but all of these states are related to the UI. Behaviors and triggers also operate based on events or act on generic controls and should not be designed with dependencies on the underlying data and business logic. Even code-behind is typically written to facilitate certain aspects of the UI. More complex code should go somewhere else—not because there is a rule that code-behind is not allowed, but because more complicated algorithms need to be tested, and having a separate and decoupled class makes it easier to test without having to wire up a full UI.

So where does the bulk of presentation logic go, and what is responsible for maintaining the business state of the application? This state includes the data that is being presented as well as the status of various commands and processes that both drive the UI and respond to user inputs. The answer is the essence of the MVVM pattern and the one element that makes it unique: the view model.

The View Model

The view model is what makes MVVM unique. It is simply a class that holds the responsibility of coordinating the interaction between the view and the model. The view model is where the bulk of the presentation logic should reside. In my opinion, a well-written view model can be tested without creating any views and has three main methods for communication with the view:

  • Data-binding
  • Visual states
  • Commands and/or method calls

With this definition in mind, you’ve already created a view model. In the previous example using countries and states, the class that held the lists of states and countries was the view model. View models typically implement the property-change notification interface and one of the validation interfaces, and they also have some type of connection to the Visual State Manager. (I’ve seen some fairly elaborate hacks try to launch storyboards from view models when a simple visual state transition was all that was needed.)

In the previous examples, you used one of two methods to instantiate the class that functions as the view model. The first was to declare an instance in the resources and then use a static reference to bind to the class. The second was to instantiate the class directly in the data context definition for the root panel of the control, most often the grid called LayoutRoot. This approach creates a direct dependency between the view and the view model. Oftentimes you’ll want to share the same view model between different views (for example, when each view is a different representation of the same data) or you’ll want to dynamically change the view or view model based on a condition. It is also popular to use a design-time view model to represent design data, so the view model may be different during design and runtime. What is the best way to resolve this binding?

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020