© Jesse Feiler 2018
Jesse FeilerBeginning Reactive Programming with Swifthttps://doi.org/10.1007/978-1-4842-3621-5_12

12. Thinking Reactively

Jesse Feiler1 
(1)
Plattsburgh, New York, USA
 

This chapter will help you put the concept of reactive programming in context with other programming styles, patterns, and paradigms. In the simplest non-jargon description, reactive programming is programming that makes it possible to easily handle modern software projects and apps that are likely to involve multiple users working at the same time with the same data.

Half a century ago it was possible to think of programming in the style of Hello World (the first program many people learned in classes). In Hello World, you type in a few lines of code (one to three, depending on formatting), and the program displays or prints the text, “Hello World.”

More sophisticated programs in this vein allow users to interact with a Hello World program by typing in a word or phrase that the program will work with. Thus, the transcript of a sophisticated version of Hello World might look like this:
Good Morning. What is your name?
Jesse
Good Morning, Jesse

The sophistication of the program lies not only in the fact that the user can interact with it, but also in the fact that the program can determine whether to greet the user with Good Morning or Good Afternoon.

Today, we are looking at much more complex systems that involve multiple users who have expectations of real-time updates so that they can see and participate in the activities of friends and colleagues. The tools we used in the days when we thought that Good Morning (instead of Good Afternoon) was great are stressed when we need to deal with these more complex systems.

This chapter will give you an overview of the tools that we need to use today (particularly those involved in RxSwift) as well as the terminology that is used to describe the tools and the products we are creating.

What Are We Developing?

In the earliest days of computers, the instructions to the computers were called programs. Groups of programs were often combined into systems in which the individual programs sometimes interacted and, in other cases, where they addressed issues related to the data involved in the programs.

The earliest programs were run by computer operators and schedulers. During the 1970s, when time-sharing and networks became available, a single large mainframe computer could be used for multiple programs running more or less simultaneously. In this environment, the running of programs devolved to users who started to use application programs that were designed to be run without technical assistance from schedulers and programmers. (Examples of early application programs were spreadsheets like VisiCalc and the first word-processing programs.)

Application programs designed for use by users rather than by computer specialists were gradually referred to as applications to distinguish them from the programs that run the computers themselves, which were often called system programs .

With the advent of smartphones, application programs got a further name simplification: apps. For a brief period of time, some people attempted to distinguish between application programs (for personal computers) and apps (for mobile devices), but that distinction never caught on (fortunately!).

Tip

There’s more information on the earliest programs in History of Programming Languages, edited by Richard L. Wexelblat, published by Academic Press (ISBN 978-0127450407), which covers languages up to 1980 (that is, before C). A second volume, History of Programming Languages II, edited by Thomas J. Bergin and Richard G. Gibson, is published by Addison-Wesley Professional (ISBN 978-0201895025). It covers languages post-1980—languages including C, Smalltalk, ALGOL, and C++.

Today, we are seeing the functionality of apps being packaged in new ways, such as extensions in Cocoa and Cocoa Touch. The technologies and user interfaces are evolving rapidly, but in this book, the end product of development is generally referred to as an app or program even though it may be an extension.

The process of creating an app or program is referred to as coding (the original term from the early days of computers that has come back into fashion) or programming. Developing is the term often used to describe the production of an app or program together with its documentation, promotional or marketing materials, and training and sustainability tools.

Approaches to Programming

There are several overlapping ways of describing and categorizing development today. This section will provide you with a quick overview of some of the key concepts and terminology that are relevant to RxSwift. There are many books and other resources available that you can use for further investigation. What is important now is for you to know what the concepts are that you need to use and understand.

Tip

Wikipedia is a great resource for more information on these topics because its community of updaters has a lot of members of the technology world who make it their business to keep the articles current .

The reasons for such a variety of frequently overlapping terminologies and concepts are beyond the scope of this book. Suffice it to say that a combination of fast-moving development projects along with the need to provide detailed technical descriptions and marketing promotions of tools as well as end products have helped to provide what sometimes seems like an endless smorgasbord of jargon.

The terms and concepts can be divided into three groups, each of which is described more fully later in this chapter:
  • Programming paradigms describe programming languages. When a user runs a program or app, it is unlikely that he or she will know what programming language it is written with, much less which paradigm(s) in that language are used. A specific language may use several programming paradigms.

  • Design patterns are ways in which recurring tasks needed in object-oriented programming can be implemented. They may be visible to the user in the performance of the app, but they also may be strictly internal. Because they are designed to be used in object-oriented programming, they can be implemented in any language that supports the object-oriented paradigm. A given app or program may use multiple design patterns (or none at all).

  • Processing configurations are the ways in which computers and their major components, such as processors and memory, are organized and connected. Although processing configurations are determined by the hardware on which an app runs, operating systems often provide features that minimize the differences so that a single configuration may at different times behave in different ways. (Look at the Grand Central Dispatch documentation in Cocoa and Cocoa Touch for an example of how this can work.)

Programming Paradigms

The main programming paradigms that matter to you if you are going to use RxSwift (and many other modern tools) are three that describe the program’s structure and another three that describe how a program or app operates. (These are just the most common programming paradigms that are important for you in the RxSwift context.)

Structural Paradigms

The issue of programming paradigms began to be discussed in the late 1950s and 1960s when most of today’s most commonly used languages were developed. It was necessary to describe them, and so these paradigms were identified and named. The main structural paradigms were reactions to the spaghetti-code programs that were frequently written. These programs consisted of line after line of code in one continuous program. Control could be transferred from one line to another because most lines were identified with a name or number. The term spaghetti-code was used to refer to the jumble of lines of code that were executed in complex and often unpredictable sequences.

To get rid of the spaghetti-code issues, these three concepts evolved:
  • Structured programming uses subprograms (logical collections of statements) to provide a structure for the program. Depending on the language, these subprograms are called methods, functions, or procedures. When control is transferred, it is transferred from one subprogram to another rather than to a specific line of code.

  • Procedural programming uses subprograms. They often take input data in the form of parameters and may return result values. At run time, the parameters of a subprogram are replaced by actual values—arguments.

  • Object-oriented (OOP) programming lets you describe objects that can encapsulate both data and functionality (or both or neither). Objects can contain subprograms such as functions or methods. Often, objects correspond to real-world concepts such as a customer, a place, or an idea.

Operational Paradigms

These paradigms describe how the commands are written.
  • Imperative programs consist of instructions to the computer to carry out specific tasks in a specific order. Conditional statements such as if let you modify that order, but the essence of imperative programs is the imperative instructions. (This term is used in the same way that it is used in language.) Tools such as Reactive Extensions (ReactiveX) help imperative languages work with sequences of data that may be either synchronous or asynchronous, thus somewhat bridging the distinctions between the two techniques.

  • Declarative programs declare what the results of operations should be. Whereas imperative programs specify what is done as well as how it should be done, declarative program paradigms specify only what is done: the program or operating system is tasked with doing it in the most appropriate manner. Declarative programming languages include instructions designed to make it clear what these end results should be.

  • Functional programs are a subset of declarative programs. They require that the program components be the sole determinants of the results of an operation such as a procedure or function. In other words, global variables and environmental settings are not used within the functions of a functional programming paradigm.

You can find a comparison of common programming paradigms on Wikipedia: https://en.wikipedia.org/wiki/Comparison_of_programming_paradigms .

Design Patterns

Design patterns are patterns or routines that can be used in similar situations. You can find them in many places, including a pattern in a house for how doors and locks are configured as well as in software. When used in the context that includes RxSwift, the term refers to a book that was published in 1994 and refers to design patterns in object-oriented software.

Tip

Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides with a foreword by Grady Booch is published by Addison-Wesley Professional (ISBN-13 978-0201633610). The authors are often referred to as the gang of four.

The design patterns are divided into three categories:
  • Creational design patterns are used to create objects.

  • Structural design patterns are used for purposes such as connecting two objects.

  • Behavioral design patterns are used to manage behavior and processing. ReactiveX uses the iterator and observer design patterns:
    • Iterator. This pattern lets you traverse some structure to get the next element (the pattern lets you specify what the sequence is).

    • Observer. With this pattern, you define a one-to-many relationship between an observer (one) and observed elements (many or none). It is a key feature that the observed element(s) doesn’t know anything about the observer. An observed element publishes a change, and any observers receive a notification, but the observed element doesn’t need to directly notify any observers.

Processing Configurations

The third collection of terms and concepts, processing configurations, is one that many developers skip over. What happens inside the processors is something that we take for granted. Simple apps such as Hello World are no longer good models for the code that we need to write, and the idea of a computer as a single device is also outdated. Almost every smartphone today runs with multiple cores—that is, multiple processors. Operating systems designed to run on such multi-core devices can perform several tasks at the same time.

What follows is a very high-level conceptual overview of multiprocessing. The operating systems allow a task to run on whatever core is available, and it can run as if there’s only one core. To work around slow devices (printers, networks, and so forth), a task can be quickly stopped and packaged with its code and resources; that stopped task can then be put aside while something else executes.

The ability to pick up a task and move it aside is generalized beyond just waiting for a slow device. If a task can run independently of other tasks, it can run on one core while some other task runs on the first core.

With such use of multiple cores, the operating system and, to a lesser extent, the task software must be able to be split into independent tasks that can be run on separate cores. To get the most out of the available cores, it is important to keep track of what memory is required for each task as well as to provide a mechanism for synchronizing the tasks at points where they can (or cannot) share memory.

In thinking about this in terms of ReactiveX, it’s necessary to distinguish between tasks or parts of tasks that can run independently (asynchronously) and those that must run in coordination (synchronously).

The goal of system software designers is to make multiprocessing possible with as little intervention by the app developer as possible. It should just happen . . . in an ideal world. With the introduction of Grand Central Dispatch (GCD) in OS X 10.6 (2009) and iOS 4 (2010), existing concurrency code in the operating systems was rewritten to make the use of multi-core devices possible with little difficulty to developers. What is key to the successful use of GCD is the use of queues of tasks. You add tasks to queues, and GCD takes over.

It is important to remember that the efficient use of multiple cores relies on developers’ using queues properly. Fortunately, ReactiveX incorporates most of the core manipulation into its RxSwift objects.

For now, just remember that asynchronous processing is built into RxSwift.

Introducing Reactive Programming

There’s a commonly repeated description of reactive programming on Wikipedia: “reactive programming is an asynchronous programming paradigm concerned with data streams and the propagation of change.” That is true, but it requires a substantial understanding of the background terms, such as asynchronous programming paradigm, data stream, and propagation of change. You have an overview of asynchronous programming in the previous section. For now, consider a data stream to be just that—a flow of data that can be on its way to a printer, communication device, or other part of the app. Propagation of change refers to the ability of an app to respond to a change in its environment and pass that change on appropriately. (That’s exactly the meaning in English of the words—it’s not specifically a technical concept.)

Focusing on ReactiveX

The basic description of ReactiveX is concise in its documentation: “The Observer pattern done right.” That, too, requires some background knowledge, but the focus is just on one thing rather than the three in the previous description: the observer pattern. The fuller description is “ReactiveX is a combination of the best ideas from the Observer pattern, the Iterator pattern, and functional programming.” The website is at http://reactivex.io . A further clarification is, “ReactiveX is more than an API; it’s an idea and a breakthrough in programming.”

Note

Observer and iterator patterns as well as functional programming are discussed in the previous section.

The heart of RxSwift (and many other reactive programming projects such as RxJava, RxJS, Rx.Net, RxScala, and RxClojure) is the ReactiveX library. ReactiveX itself is a collection of open source projects. The ReactiveX project is also open source, licensed under the Creative Commons Attribution license. Code samples are licensed under the BSD license.

Summary

This chapter has provided an overview of the technologies on which RxSwift relies. Nothing is new here or specific to RxSwift. In the chapters that follow, you will see code that implements these design patterns in RxSwift, and you will find real-life examples of their use.

At this point, you’ve seen how to download RxSwift from GitHub and how to build it in Xcode. It’s time to look at the basics of the code you will use.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.220.233.134