Data Mesh Principles and Logical Architecture The great divide of data What do we really mean by data? The answer depends on whom you ask. Today’s landscape is divided into operational data and analytical data . Operational data sits in databases behind business capabilities served with microservices, has a transactional nature, keeps the current state and serves the needs of the applications running the business. Analytical data is a temporal and aggregated view of the facts of the business over time, often modeled to provide retrospective or future-perspective insights; it trains the ML models or feeds the analytical reports. The current state of technology, architecture and organization design is reflective of the divergence of these two data planes - two levels of existence, integrated yet separate. This divergence has led to a fragile architecture. Continuously failing ETL (Extract, Transform, Load) jobs and ever growing complexity of labyrinth of data pipel...
Five Essential Advanced Concepts in Object
Oriented Programming, Explained Intuitively
Object-Oriented Programming is one of the most important concepts every programmer should know. Universally recognized as one of the best ways to write clean and readable code, understanding how to use and manipulate sometimes complex relationships between objects.
This article will cover the following Object-Oriented Programming concepts, with diagrams, analogies, and code:
Fundamentals and Instantiation
Inheritance
Composition
Encapsulation
Polymorphism
Abstraction
Code provided is in Python.
Fundamentals & Instantiation
Object Oriented Programming is a method of programming that groups code structures into objects, which can contain internal variables and functions. For instance, consider a human resources department that needs to determine payment for its employees. It can create a generic employee object with initialization parameters and functions.
Image for post
Image by author
Consider, then, an employee named Jack, who receives $30 per hour and just got the job (balance for payouts is 0). He could be represented using the Employee template, filling in some of his unique variables. The construction of an object based on the ‘template’, or more formally, a class, is known as instantiation.
Image for post
Image by author
Jack is an object, and so its methods and variables can be called. If we call Jack.name, we’ll get the string ‘Jack’. If Jack.pay_money() is run, the object’s balance will be updated with the corresponding payment.
Inheritance
Not all employees are the same, however. For instance, while Jack may receive an hourly wage working as a store manager, Jill might be working as a waitress, in which she receives both base pay and additional money from tips. Hence, we have the following scenario:
There are two closely related objects with much in common, like a name, balance, and base pay.
There is at least one small difference between these two objects.
One method is to construct an entirely new class, EmployeeTips, especially for employees that also receive tips by copy-pasting the internal code over. Another way to achieve this is with inheritance.
In inheritance, we construct a new class but inherit the variables and attributes of another class. Then, we can either alter existing functions with the same name or add new ones.
Image for post
Image by author
In this example, the class Employee is called the parent
class, and the class EmployeeTips is called the child class or
derived class.
Through instantiation, we can use this class for Jill. Note that even though the internal variables were not explicitly stated, they were loaded through inheritance. The same parameters used in class Employee applies to class EmployeeTips as well.
When Jill.pay_money(tips=30) is called, meaning that she earned $30 in tips, her balance increases by $50 because the updated class pays both the tips and the base payment of $20.
Composition
Composition is very similar to inheritance. Whereas inheritance involves a child class that is derived from a parent class in that its internal properties remain similar but can be edited through addition, revision, and deletion; composition involves a component and a composite class. The component class, in its unedited entirety, is part of the composite class.
Consider, for instance, a class named information whose function, print_report, prints out an employee’s internal variables in a nice, human-readable format — this would be very valuable to a human accessing the database.
Image for post
Image by author
To use the attributes and variables of this class within the class Employee, we can simply list the Information class as one of its variables.
Image for post
Image by author
Since the Information class is a class within a class, its properties still need to be called from it. In order to print out the information, one would need to call Jack.information.print_report(), assuming that Jack has already been initialized.
Composition is a simple way to stack multiple classes into one superclass, providing an elegant hierarchy to access methods within objects and subobjects.
Since composition and inheritance are so similar, it can be difficult to find out which to use. Composition should be used for pure hierarchies, like squares and rectangles. Although it is possible to use inheritance to create two separate methods to find the area, it is much easier to simply include a special case: if the length and width are equal, run the program to find the area of a square. On the other hand, inheritance can be used where such a hierarchy is less clearly outlined and objects need to be more significantly edited.
Encapsulation
We don’t want just anyone to be able to pay an employee without any security, so let us implement a security measure. A function confirm requires a password, checks if an entered password matches the password on file, and only runs the payment function if the passwords are equal.
Image for post
Image by author
This works, but there’s one issue — instead of using the secure method, like Jack.confirm(‘i_am_jack2016’), someone could directly run Jack.pay_money(), which would bypass the password confirmation.
In order to prevent this, we need to lock parts of the object from instantiation, or use encapsulation. In this case, the .pay_money() class function needs to be locked such that it cannot be called externally, only within the object through other internal functions like confirm(). This is done by placing two underscores before and after a name, like __pay_money__. When someone tries to access the function externally, it yields an attribute error (‘Employee’ object has no attribute ‘pay_money’).
Encapsulation is used for a few reasons:
Allows for security in applications.
Promotes a smooth experience for users without exposing the complexities of the backend.
Improves the development process, preventing potential loopholes due to lack of restrictions on scope.
Polymorphism
Polymorphism is an important aspect of classes, and allows for referencing of the same method across several classes. The word ‘polymorphism’ literally means ‘the condition of occurring in several different forms’.
For example, consider two objects, cat and dog. These both have an identically named function, make_sound(), which causes cat to print “meow!” and dog to print “woof!” Because of polymorphism, the following statement is legal and will output “meow! woof!”.
Furthermore, polymorphism works with other entities like parameters in functions: (assuming that .make_noise() returns a string instead of printing)
Abstraction
Abstraction is almost identical to inheritance, but used in scenarios where we don’t want the parent class to be instantiated. Consider, for instance, the class vehicle — it is quite an abstract concept, because it could really be anything from a bus to a train to even a horse. However, this abstract concept has a few inherent attributes, like the number of points the vehicle touches the ground on (four times for cars, two times for bicycles).
In this case, it makes sense to create a class with the base attributes of vehicle, like a class named car, but not to instantiate the class vehicle as its own object. In types of relationships where the parent class is too abstract to be instantiated, abstraction can help.
Let’s rethink our previous model of employee instantiation. Let’s create the abstract idea of an Employee.
Image for post
Image for post
Image by author
Then, based on this abstract idea of an Employee, we can create a manager class with more specifics on what the abstract method is through inheritance. do_taxes() and oversee_operations() are hypothetical replacements for what the manager might be doing when do job is called.
Image for post
Image for post
Image by author
From here, objects can be instantiated. For instance, if Jack was a manager, we would say Jack = Manager(name=’Jack’). Because the Employee class is an abstraction, it wouldn’t make sense to do something like Jack = Employee(), since it contains an abstract method do job that isn’t defined.
Yorumlar
Yorum Gönder