
Information Computation means a process engaging a computer (a physical device) to process information as a series of actions or steps taken to achieve a particular result or help to fulfill a task - shortly to solve a problem. The main challenge is that information is abstract, it is a kind of knowledge that cannot be processed directly by any physical device. This lesson covers two main topics. That is dealing with the data recognized as the information representation and with the using a program as the behavior description implementing an algorithm. The course is a part of the Programming in Practice series of courses. This lesson covers introductory topics.
The main goal of this lesson is to explain the meaning of the information term as a component of the course title to create a starting point to improve your further understanding. In this context, we must be aware that the information should be recognized as a kind of knowledge describing the state and behavior of a process in concern. The process that we want to monitor or control, with the use of devices, with the use of technology - to be precise - with the use of computers to achieve the goal automatically - I mean minimizing human interaction. This kind of information we may call process information. The main challenge we must face up is that the process information cannot be directly applied or used by any physical device including but not limited to computers because it is abstract. This lesson learns how to overcome this obstacle and is an introduction to more general topics related to types offered by modern programming languages. We will use types to implement the process information in the context of a programming language.
This lesson is the next step of the introduction to general aspects related to controlling a device as a foundation of information computation. Information computation means an activity engaging a computer (a physical device) to process information as a series of actions or steps taken to achieve a particular result or help fulfill a task. The information describing this series of actions or steps taken we call an algorithm. Again, the algorithm is a knowledge to be deployed to solve problems related to this process. Again it is an abstraction. Unfortunately, the computer is a physical device and cannot process any abstraction. During this lesson, we will learn how to implement abstraction to overcome this obstacle by utilizing the computer as a programable device. To run, the computer needs a program to help solve our problem. Computation is the activity of running a program that must be developed in advance using a programming language. Let me remind you that it is the main goal of the software developer job, your professional carrier.
Previously we learned that abstract information may be represented using a computer-aware stream of signs using a coding system. Finally, it must be a binary representation. The main goal of this lesson is to learn how the coding system we used to represent information - that is abstraction - may be replaced by the type notion that is well known and widely accepted concept for modern programming languages. The types enable us to focus on the domain of values but not low-level values representation. At the end of this lesson, you will recognize the types as an implementation of the information and algorithm.
The main goal of this lesson is to recall the basic rules of the custom type definitions. Custom types are used to implement information and algorithm in concern because they are abstract and cannot be a direct subject of computation. After the lesson, you will be able to declare your custom type, distinguish between value and reference types, get background related to static class, and reuse the singleton pattern. All of that we will discuss in the context of the examples gathered in the TP repository. Let me stress that by design this lesson is also an introduction to object-oriented programming so intentionally I will not discuss all the available methods of types definitions.
In my opinion, a key to understanding the course is a good understanding of the object-oriented programming concept as a method to solve problems involving instance operations of unknown type. Hence, I gonna spend this lesson to recall the main principles of this concept. I will remind you of such object-oriented programming terms as class, interface, encapsulation, inheritance, implementation, polymorphism, and so forth. I will pay special attention to the constructs that are characteristic of these terms for example abstract and virtual members. I want to stress that not all programming languages provide the same constructs but we can find many similar ones, so I hope that this discussion will also help to reuse the learning outcomes and port them to other programming languages if needed. We will come back to this topic many times throughout the rest of the course.
Let me recall that the course leverages strongly typed programming languages. This means that they encourage and even force designers to use types for internal consistency checking of programs. The rules for checking the compatibility of types, apart from the rules for checking the syntax correctness of the program as one whole, must be recognized as fundamental mechanisms applied for validating the program content at design time. This strong typing approach undoubtedly increases the probability of program correctness in the context of internal information computation. If we want to pull or push data from/to external resources not directly managed by the runtime environment we must answer the question of what type they are. How to harmonize these external data types with the types defined in the program. In general, we can apply type definitions conversion, evaluate types at run time, or apply types correlation. Does it sound strange? I am pretty sure that the answer is yes. The main goal of this lesson is to learn more about it. Especially, let's talk about how the concept of anonymous type can help with this. I will try also to recall fundamentals related to dynamic type that can be applied to evaluate type at run time. The type conversion will be a subject of independent episodes embedded in separate courses, so I will only mention this mechanism in this lesson. Again, after the end of this lesson, you will be familiar with the anonymous types concept.
Limiting the scope of our discussion only to methods applicable at design time we know that for the strongly typed programming languages, the type of a variable may be devised by a developer or inferred by the compiler. We must keep in mind that there is a next option. Another possibility is an auto-generated text of the required type definition from metadata using a development tool. The main goal of this lesson is to learn more details related to partial definitions that allow us to address this issue and avoid text conflicts. I will try to answer why we need this concept and associated language constructs to implement the separation of concern using this text management mechanism. Partial definitions are used to blend separate parts finally making up a type definition as one whole. The discussion will be general but conducted using a concrete language development environment. Hopefully, you will be able to leverage the learning outcomes in other development environments if needed.
It is obvious that the possibility of reusing the outcome of previous programming work is extremely important because it improves economic efficiency, is beneficial for reliability, and minimizes training costs. Together it decreases the total costs of software program development. During this lesson, you will learn how new custom types may be defined thanks to applying parametrized templates and improving this way reusability of previous work. We will learn more about generic types definitions. Because the generic definitions ensure repeatability we may recognize them as an alternative to object-oriented programming to a certain extent. This, as we know, decreases the total costs of software development. The main idea behind applying the generic types and methods is the possibility to use a kind of parametrized script to automatic generation the final custom type definition compliant with a template. During this lesson, you will gather more detail about the rules governing this text management mechanism of a program.
The main goal of this lesson is to learn more about the architecture of the computer program in the context of typical responsibilities related to streaming, structural and graphical external data access, and the process of software development. A computer program begins its life cycle as a text that follows the rules of a selected programming language. To decrease the cost and improve the performance of the program development process, the text of the program is often organized into autonomous fragments addressing typical responsibility. There are many design patterns applicable to help implement typical algorithms but the layered model is well-suited to be applied to the program as one whole. The main goal of this lesson is to address the challenge of how to improve software development performance by applying the layered design pattern to the programs as one whole. We will also examine the benefits expected thanks to organizing the program text in compliance with this design pattern. We will learn this design pattern from the information computation point of view. System architecture and application architecture topics are out of the course scope. It is the first lesson addressing the proposed layered design pattern. You will learn the main benefits of this approach related to teamwork and testing to name only the most important topics. The next lesson contains more examples illustrating how to deploy this pattern in practice.
The main goal of this lesson is to learn more about how to implement the layered design pattern. The previous lesson covered details justifying the benefits of this design pattern and the main rules that can be used to deploy this design pattern in practice. Applying these rules should be very easy to use this approach to deploy layers of books, carpets, and so ones. Unfortunately, any computer program begins its life cycle as a text that follows the rules of a selected programming language. You will learn how to decrease the cost and improve the performance of the program development process in the long run by organizing the program text into autonomous parts hierarchically related to each other. There are many design patterns applicable to help implement typical algorithms but the layered model is well-suited to be applied to the program as one whole. The main challenge we must face during this lesson is learning all about computer program layered architecture deployment in practice.
This lesson and the next one are on inter-layer communication. The main goal of this lesson is to learn more about the issues related to the deployment of the bidirectional communication of layers. We will start addressing the definition or rather a description of the communication concept pointing out that this term is related to the run-time stage of any program life cycle. Despite this, it must be programmed during the design time, hence, may be recognized as a crucial challenge for any software developer. This lesson will introduce you to the topic of how to implement inter-layer bidirectional control and data flow using a unidirectional layered architecture. The next class will learn you how to deploy this communication based on examples.
The main goal of this lesson is to learn more about how to deploy the bidirectional communication of layers stack. From the previous lessons we know that, by design, the layered program design pattern means its organizations, in which we can distinguish independent entities of a program related to each other making a top-down hierarchy. The distinguishing feature of a layer is that all definitions belonging to a layer are self-contained internally in a layer or may refer only to the declarations visible from the layer below. In other words, the top-down relationship means that the layer above only refers to the declarations available by the layer below. We discussed it already stressing that it is a compile-time pattern. At run-time, we must consider control flow and data flow in both directions for sure. It is the second lesson related to the bidirectional communication of the layers. This time we will focus on deploying bidirectional control and data flow using a unidirectional layered architecture based on the previously introduced examples.
During this lesson and the next one, I want to conclude topics related to algorithm implementation with a nontrivial example. You will learn more about the fundamentals of a dependency injection design pattern. You will learn two scenarios where we must bother with a problem that required instance operation referees to the type declaration that is invisible in a place of invoking the operation for some reason. You will learn that in that and similar occurrences, the dependency injection could help. The dependency injection concept we know from the previous lesson. To address this impossibility of instantiating a type in a location where it is invisible, we are using abstract variables to transfer an instance from the creation to the usage location. Previously we used it to implement inter-layer bidirectional communication implemented based on a unidirectional layered software program archetype where types defined in the paper layer are invisible by definitions belonging to the layer beneath. Now it is time to investigate this pattern in a more general context to use this pattern to solve also other problems. After this lesson, you will be aware that we need an additional design pattern beyond the object-oriented one to address this issue.
The main aim of this lesson is continuation further investigation on the dependency injection (DI) design pattern deployment. The dependency injection concept we know from the previous lesson. From the previous lesson, we know that the DI could be used to address the following problems: (a) program validation, (b) separation of concerns, (c) dependence on technology, (d) simultaneous development, and (e) determining the sequence of objects creation. All topics except the last one (e) can be considered as a problem derived from dependency on invisible type definitions. I'll return to this issue shortly but it is out of the scope of this lesson. To get straight to the point, we will try to understand the DI by examining the examples from the repository related to the program validation only. Other topics have been already discussed so now we may safely skip detailed discussion of them.
This lesson is a kind of recap of the course learning outcomes. The main goal of the course was to concentrate on adopting learning - it means focusing on knowledge adoption covering concepts, standards, and best practices, to name only a few. I focused on learning rules related to information computation but not training in a particular language or development tool.
We started with the statement that the course title - that is Information Computation - is a bit provocative because information - as a kind of knowledge - is abstract and cannot be directly processed by a physical computer even if a computer and implemented algorithm make up a powerful artificial intelligence bot that is capable of understanding human speech and producing in-depth writing that humans easily understand.
While learning, we distinguished the following terms: **process information** and **algorithm**. The **process information** describes the state and behavior of a process in concern. In turn, the **algorithm** is a knowledge to be deployed to solve problems related to this process. Together both are indispensable to employing a computer to automate the process of information processing using a device.
After the general introduction, you will revisit topics related to process information implementation including types construct, the object-oriented programming concept, and text management mechanisms allowing you to improve the software development process and make it more reliable.
During the last part of the lesson, you will have the opportunity to recall rules related to the design pattern governing the organization of the program text as one whole. You will be able to apply the layered design pattern, implement bidirectional communication using unidirectional layers dependency, and be familiar with using dependency injection to overcome problems with limited visibility scope of type declarations in some circumstances.
The course is about information computation in practice. We will start with the statement that the course title is a bit provoking because information is abstract and cannot be directly subject to processing by a computer even if the computer and implemented algorithm make up a powerful artificial intelligence bot that is capable of understanding human speech and producing in-depth writing that humans easily understand. While learning, we distinguish the following terms: process information and algorithm. The process information describes the state and behavior of a physical process in concern. In turn, the algorithm is a knowledge describing how to solve the problems related to the physical process in concern. The course addresses topics that are vital for overcoming in-practice this inconsistency to employ computers.
The main goal of the course is to concentrate on learning - it means focussing on knowledge adoption. I focused on learning rules related to information computation but not training in a particular language or development tool. To make the learning outcomes practical examples are indispensable. To avoid overloading the examples with details unimportant for investigated topics I propose to apply extended examples. By extended examples, I mean examples that can be executed as independent unit tests. This way, you can observe not only a pattern but also trace the behavior. I believe that it should also improve the reusability of the examples. By design, the unit tests are used to validate the correctness and consistency of a program. The role of the unit tests included in the attached examples is significantly different. They are created with teaching values in mind. By design, they are used to make the examples intelligible and add the possibility to analyze also the behavior of the code patterns presented here. As a result of this approach, the examples are not obscured by a bunch of unimportant details needed to execute the examples as a part of a complete program.
This course is a member of the course suite titled Programming in Practice. Hence, more details about the rules overseeing this course you can find in the independent free course titled Programming in Practice - Executive Summary - consider enrolling and passing it if didn't yet.
Information Computation Fundamentals
You will learn that the process information is an abstraction and, hence, cannot be subject to processing by any physical machine, including computers. This inconsistency can be overcome by applying coding systems. In reality, this way, we are computing the data but not the information. Fortunately, this way we can address the challenge that the same information could have an infinitive number of representations. We need a driving force - an engine - to realize the processing. Today it is a binary computer. Hence, in the context of information computation, we must deal with two kinds of information: process information and algorithm. The process information describes the state and behavior of a process in concern. In turn, the algorithm is a piece of information on how to solve the selected problem. Both are tightly coupled and must be represented together using a programming language, which is suitable to be used as a recipe of the computer behavior and information representation of a process in concern.
Computers are programmable devices and need a kind of program to be controlled. To accomplish it, we use high-level languages based on an alphabet derived from the Latin alphabet. Syntax of these languages is founded on keywords borrowed from the natural English language and semantics supports object-oriented programming concept. Informally, they are designed to produce text that is more human-readable and easier to use. Modern languages consistently use the type concept to describe process information representation and algorithms implementation. The section spent on recalling information computation fundamentals is an entry point to further learning selected aspects related to types applicability and design patterns of the program text. The object-oriented programming concept is the foundation of this learning path.
Information Representation Using Types and object-oriented programming
In this part of the course, we recognize the type definitions as a part of a programming language that is a set of syntax and semantics rules governing a text of a computer program. The main idea behind custom types is the possibility to represent practically any process information to be the subject of computation. Types are used to control the program consistency if the programming language is strongly typed, therefore could improve the robustness of the development outcome. The course prepares you to define new custom types. You will learn that using modern programming languages, new types may be defined from scratch or derived from existing ones. To accomplish it very helpful is the object-oriented programming concept. Additionally, the application of this concept allows us to solve polymorphic problems and organize the interoperability of software program parts using abstraction, inheritance, and encapsulation. The abstraction may be recognized as a contract used to harmonize the development process of the software program parts.
During the course, we spent also a reasonable amount of time learning selected text management mechanisms enhancing the type definitions process. After the course, you will understand the main idea and scope of usage of anonymous, partial, and generic definitions to represent process information using types.
As a result of using anonymous types, the compiler infers type definition from the expression evaluated as a value. During the course, we get more about how to use this definition method of a custom type to represent external data and use it for consistency checking. External data is not subject to detailed examination but it is recognized as data managed outside of the process hosting the program.
Typically, for strongly typed programming languages, the type of a variable may be devised by a developer or inferred by the compiler. During the course, we examine the next option, which is an auto-generation of the required type definition from metadata using development tools. During the course, you learn more about how to blend autogenerated parts with the developer ones.
The possibility of reusing the outcome of previous work is extremely important because it improves economic efficiency, is beneficial for reliability, and minimizes training costs. The generic definition concept is a next text management programming language feature that allows automation of the custom type definitions by using parametrized templates.
Algorithm implementation
Process information representation and algorithm implementation are tightly coupled and must be the subject of a computer program development using a selected programming language. Computer programs begin their life cycle as the text that must be compliant with this language. The course addresses methods and patterns that may be applied to manage the program text as one whole with the purpose to make teamwork easier, allow independent testing, decoupling the development outcome from the technology change, and make scalability easier, to name only the most important. To decrease the production cost and improve robustness, it is proposed to organize the computer program text into autonomous fragments addressing typical responsibilities. There are many design patterns applicable in this respect but the layered design pattern is best suited to be applied to the program as one whole
The program development should be commenced by researching knowledge helpful to solve a problem in concern or achieve the computation goal. This knowledge as one whole we call algorithm. The separation of concerns is a very useful concept while working on algorithms. From sociology we know, that the separation of concerns improves our performance of thinking because as a result, we may think about independent topics with minimal overlapping between them. So to improve our productivity we must leverage separation while working on the computer program text. You will learn that the main challenge is to decide when and where we should deal with the separation of concerns - while thinking about the solution or while implementing it as a text.
It is proposed to implement this separation by applying the program's layered design pattern. During the course we learn that thanks to this approach the following benefits may be accomplished: separation of concerns, simultaneous development, independent testability, resistance to changes in technology, and scalability. Finally, you will learn how to decrease development time and time to market. Usually talking about a layered design pattern applied to the program as one whole we may distinguish three layers: the presentation, logic, and data layers. Getting more about implementation, the responsibility of layers, and the expected benefits are the next learning outcome.
Layers may be implemented using sets of custom-type definitions. These definitions must either be self-contained within the layer, or they may depend on declarations that are exposed by the layer beneath it. During the course, you will learn how to recognize the membership. To make the layer unambiguous it must be assumed that any type belongs only to one set, to one layer. This way we convert the discussion about mathematical sets to the examination of types grouping. The main goal is to keep the discussion as practical as possible.
By design, the layered program design pattern means its organizations, in which we can distinguish independent entities of a program related to each other making a top-down hierarchy. The top-down relationship means that the layer above only refers to the declarations exposed by the layer below. You will learn that it is a compile-time pattern. At run-time, we must consider control flow and data flow in both directions between layers. Hence, the next challenge addressed by the course is how to implement the bidirectional communication of layers at run time using a unidirectional dependency relationship. You will learn that inter-layer communication may be categorized into control flow, data transfer, and event notification. During the course, to make the learning outcome practical, we explore various examples of interlayer communication, including but not limited to properties, callbacks, events, reactive programming, and dependency injection. Some of them may also be referred to as inversion of control.
The next part of the course covers the applicability of the dependency injection design pattern in practice. During the course, it is stressed that the main point of this design pattern is an assignment to an abstract variable a reference to an instance of an invisible type at the intended location for some reason. I named this pattern dependency injection to somehow distinguish this scenario from using just object-oriented programming alone. In this case, we are using object-oriented programming to deal with the separation of concerns. One concern is the usage, and the second one is the implementation of a concrete type. Hence, shortly the dependency injection is a design pattern where we are using an abstraction in place of an unknown for some reason instance of a concrete reference type to transfer this instance from one place to another. You will investigate practical examples demonstrating independent testing and bidirectional inter-layer communication.
This particular design pattern implements abstraction to create an agreement between the creation and usage of an instance. The abstraction is employed to specify the property type (property injection) or the formal parameter type of the instance method or constructor (method or constructor injection). This design pattern eliminates the requirement for visibility of a specific definition of the concrete type in the program's intended location.