This document discusses software architecture and design principles. It covers topics like moving from n-tier to service-oriented architectures, SQL to ORM databases, and RAD to MVC design patterns. It also discusses SOLID principles like the single responsibility, open/closed, Liskov substitution, interface segregation and dependency inversion principles. Finally, it provides examples of applying these principles in Delphi code using interfaces and dependency injection.
EKON20 Conference, November 2016
Monolithic rich Windows applications are not enough for our customers. We are often requested to provide a web front-end, or a REST server to be consumed by mobile or thin clients. Integrating n-Tier architecture to an existing project is challenging. Some good practices, based on industry standards and proven design patterns (like uncoupling or SOLID) can be mind-breaker for RAD developers. In this session, we will define some architectural aspects of SOA, ORM and MVC/MVVM, and what our Open Source mORMot framework offers to ease this transition.
EKON20 Conference, November 2016
Monolithic rich Windows applications are not enough for our customers. We are often requested to provide a web front-end, or a REST server to be consumed by mobile or thin clients. Integrating n-Tier architecture to an existing project is challenging. Some good practices, based on industry standards and proven design patterns (like uncoupling or SOLID) can be mind-breaker for RAD developers. In this session, we will define some architectural aspects of SOA, ORM and MVC/MVVM, and what our Open Source mORMot framework offers to ease this transition.
Visual Basic .NET (VB.NET or VB .NET) is a version of Microsoft's Visual Basic that was designed, as part of the company's .NET product group, to make Web services applications easier to develop.
Common Object Request Broker Architecture - CORBAPeter R. Egli
Overview of CORBA (Common Object Request Broker Architecture) object technology.
CORBA is a distributed object technology (DOT) that extends the remote procedure call semantics to distributed objects.
Object interfaces are described in a formal language called IDL (Interface Description Language) that allows generating stubs and skeletons through an IDL compiler.
Towards Semantic Modeling of Network Physical DevicesTobias Walter
Talk in the Doctoral Symposium of 12th International Conference on Model Driven Engineering Languages and Systems, MoDELS, 6 October 2009, Denver, United States.
These projects demonstrated my ability to program Visual Studio .Net with C# as the programming language in 2 separate projects.
The Purpose of the first project was to build parts of the business tier for a retail Company. The goal is to create and test two assemblies. The first assembly is a class library project called Foundation. It will contain various interfaces and base classes.
The second assembly is also a Class Library project and its called AppTypes and it will contain various entity, collection and exception classes used by various business processes.
The Objective of the second project Is to create a database to support the principal functions of a library’s day-to-day operations: adding new members (adult and juvenile) and checking books in and out.
A Windows Forms-based front end application that will provide a librarian with a visual interface through which he or she may perform the desired functions.
And the project goal is to Design and develop a front end application that satisfies the four basic functionalities: Add Adult, Add Juvenile, Check in a book, Check Out a book.
Develop code that is easily maintainable.
Provide validation for all required fields.
Provide adequate error handling.
Produce a user interface that is intuitive, requiring minimal training for users while minimizing resource utilization.
EKON20 WorkShop, November 2016
The Open Source mORMot framework is a huge set of units, with a lot of features. It allows Delphi and FPC to eb true competitors for business projects. In this workshop, we will present how its ORM leverages SQL and NoSQL databases, and how interface-based services ease SOA development. We will show some several cross-cutting features, like SynTests (and stubs/mocks), SynLog, SynMustache, SynDB, SynMongoDB, SynSM, SynPDF, SynCrypto or SynEcc. High-level presentation of the involved concepts will always be followed by some sample code.
Some slides, as presented during EKON20 conferences, about the mORMot Open Source project, a Delphi/FPC professional framework featuring highly integrated SOA, MVC, ORM, SOLID over SQL and NoSQL databases.
Visual Basic .NET (VB.NET or VB .NET) is a version of Microsoft's Visual Basic that was designed, as part of the company's .NET product group, to make Web services applications easier to develop.
Common Object Request Broker Architecture - CORBAPeter R. Egli
Overview of CORBA (Common Object Request Broker Architecture) object technology.
CORBA is a distributed object technology (DOT) that extends the remote procedure call semantics to distributed objects.
Object interfaces are described in a formal language called IDL (Interface Description Language) that allows generating stubs and skeletons through an IDL compiler.
Towards Semantic Modeling of Network Physical DevicesTobias Walter
Talk in the Doctoral Symposium of 12th International Conference on Model Driven Engineering Languages and Systems, MoDELS, 6 October 2009, Denver, United States.
These projects demonstrated my ability to program Visual Studio .Net with C# as the programming language in 2 separate projects.
The Purpose of the first project was to build parts of the business tier for a retail Company. The goal is to create and test two assemblies. The first assembly is a class library project called Foundation. It will contain various interfaces and base classes.
The second assembly is also a Class Library project and its called AppTypes and it will contain various entity, collection and exception classes used by various business processes.
The Objective of the second project Is to create a database to support the principal functions of a library’s day-to-day operations: adding new members (adult and juvenile) and checking books in and out.
A Windows Forms-based front end application that will provide a librarian with a visual interface through which he or she may perform the desired functions.
And the project goal is to Design and develop a front end application that satisfies the four basic functionalities: Add Adult, Add Juvenile, Check in a book, Check Out a book.
Develop code that is easily maintainable.
Provide validation for all required fields.
Provide adequate error handling.
Produce a user interface that is intuitive, requiring minimal training for users while minimizing resource utilization.
EKON20 WorkShop, November 2016
The Open Source mORMot framework is a huge set of units, with a lot of features. It allows Delphi and FPC to eb true competitors for business projects. In this workshop, we will present how its ORM leverages SQL and NoSQL databases, and how interface-based services ease SOA development. We will show some several cross-cutting features, like SynTests (and stubs/mocks), SynLog, SynMustache, SynDB, SynMongoDB, SynSM, SynPDF, SynCrypto or SynEcc. High-level presentation of the involved concepts will always be followed by some sample code.
Some slides, as presented during EKON20 conferences, about the mORMot Open Source project, a Delphi/FPC professional framework featuring highly integrated SOA, MVC, ORM, SOLID over SQL and NoSQL databases.
EKON20 Conference, November 2016
Starting from Michael C. Feathers “Working Effectively with Legacy Code”, we will introduce the concept of “technical debt”, and some practical patterns to integrate testing, separation of concerns, structure, re-usability, to ease maintenance and evolution of existing projects. Don’t forget that even new projects will soon become legacy… Of course, we will introduce some mORMot features which were developed to reduce your pain in this process.
A Performance Comparison Of C# 2013, Delphi Xe6, And Python 3.4 Languagesijpla
C# 2013, Delphi XE6, and Python 3.4 are the newest and most popular programming languages. These
programming languages become more popular every passing day. In this study, the response times,
memory usages, and code lengths of these languages were tested in various workloads. Whether or not
there was any significant difference between the data obtained from workloads was tested via the Friedman
test. The test indicated a significant difference. In addition, the Wilcoxon signed rank test was used for
determining the effect size. This test showed that the level of the significant difference found in the
Friedman test was high
Delphi ORM SOA MVC SQL NoSQL JSON REST mORMotArnaud Bouchez
Slides published for BeDelphi 2014 Event.
Create high performance Client Server ORM SOA REST MVC applications using Open Source Synopse mORMot framework and Delphi. Publish any SQL or NoSQL database content over JSON or XML: SQLite3, PostgreSQL, Oracle, MSSQL, FireBird, MongoDB. Define RESTful services using interfaces. Create MVC web applications, using Mustache templates. Running under Windows or Linux, with VCL/FMX clients on Mac OSX, Android or iOS/iPhone/iPad, or AJAX/PhoneGap.
SOLID principles should better be applied when designing business objects, as soon as maintainability and modularity are needed. They bring uncoupling, abstraction and clean design to Object Oriented Programming. Microservices could be seen as SOLID principles applied to the Service Oriented Architecture. In respect to a classical monolith server, thanks to uncoupling and better granularity, you may enhance deployment, ease cooperation between dev teams, introduce Domain Driven Design and/or Event Driven Design, scale horizontally and still incorporate existing code and services.
After a quick and practical review of SOLID principles, we will see how they may apply to SOA, and how Microservices could be defined using the Open Source mORMot framework interface-based services, on Windows or Linux.
Advantages of .NET over the other languages, overview of .NET binaries, Intermediate Language, metadata, .NET Namespaces, Common Language runtime, common type system, common Language Specification.
C# fundamentals – C# class, object, string formatting, Types, scope, constants, C# iteration, control flow, operators, array, string, Enumerations, structures, custom Namespaces
Those slides describe digital design using Verilog HDL,
starting with Design methodologies for any digital circuit then difference between s/w (C/C++) and H/w (Verilog) and the most important constructs that let us start hardware design using Verilog HDL.
An Introduction to the SOLID PrinciplesAttila Bertók
SOLID Principles are the most important principles of writing maintainable, easy-to-read, easy-to-write clean code. This presentation attempts to give a basic overview of these principles with some examples of violations and ways to correct them.
This presentation talks about the five SOLID principles of Object Oriented Design described by Rober C. Martin in his best-seller book "Agile Principles, Patterns, and Practices in C#". The five principle described are:
- Single Responsibility Principle
- Open-Close Principle
- Liskov Substitution Principle
- Interface Segregation Principle
- Dependency Inversion Principle
The presentation is took from the Software Engineering course I run in the bachelor-level informatics curriculum at the University of Padova.
As a follow-up of the previous session about TFB, we will discuss what kind of tuning was made to the mORMot library, and its associated TFB sample implementation, to reach the top scores in charts. How can a pure Pascal project reach 7 millions of HTTP requests per seconds? How to scale and measure on high-end hardware? Are ORM frameworks damned to slow down everything? How to circumvent the lack of “async” programming at language level? How realistic is such a benchmark?
The TFB challenge is a performance comparison of many web app platforms, exercising JSON, database, ORM, HTML templates, all over HTTP. It compares the best frameworks written in C++, Rust, Go, JS, Java, C#… and now Pascal – thanks to mORMot. In this session, we will look and compare the source code of some frameworks samples, to distinguish their typical philosophy. We will see how modern Object Pascal is still relevant, and propose some ideas for the future of the language.
The most powerful way of writing REST services is to define them via interfaces, then let the SOA/REST framework do all the routing, data marshalling and communication behind the scenes. One distinctive feature of mORMot is to define a method parameter as a notification interface, and let the server call back the client when needed, as with regular Delphi code. This session will present the benefit of defining REST services using interfaces, and how WebSockets can offer real-time notifications into your rich Delphi client applications.
The OpenSource mORMot framework has a strong set of cryptography features. It offers symmetric cryptography with hashing and encryption, together with asymmetric cryptography via private/public key pairs. Its optimized pascal and assembly engines can be embedded into your executable, but you could also call an external OpenSSL library if needed. This session will present mormot.crypt.* units, and apply them to some use cases, from low-level algorithms to high-level JWT or file encryption and signing.
During the continuous mORMot refactoring, some core part of the framework was rewritten. In this session, we propose a journey to a refactoring of a single loop. It will take us from a naïve but working approach, to a 10 times faster Pascal rewrite, and then introduce how SSE2 and AVX2 assembly could boost the process even further – to reach more than 30 times improvement! No previous knowledge of assembly is needed: we will try to introduce how modern CPUs work, and will have some fun with algorithms and SIMD parallelism.
The OpenSource mORMot is a RESTful ORM / MVC / SOA framework for Delphi and FreePascal. Some of its codebase is now about 10 years old, and it was time to clean and evolve. This year 2020 triggered a deep refactoring of the whole source code, with a full rewrite of some core components (JSON, RTTI). This session will present the version 2 of mORMot it its current state, the principles behind this refactoring, and how you may find useful gems for your own Delphi applications.
Ekon23 (2) Kingdom-Driven-Design applied to Social Media with mORMotArnaud Bouchez
To illustrate the “Kingdom Driven Design” session proposal, we will expose and comment upon the software core of a custom social media service. It will create a network of user-generated content, not only connected around people or topics, but unleashing some reference text material: literature, law, science, religion – you name it. We will discuss proper KDD architecture, data structures, and associated microservices, using mORMot’s ORM and SOA as toolbox. The code of this new social media system will be disclosed under a GPL agreement, and running on production for years to come. It should be able to scale from a few users to worldwide adoption.
After years working on Domain-Driven Design projects using Delphi for server-side processes, I eventually followed some kind of cut-back version of the DDD paradigms. Introducing Kingdom Driven Design (aka KDD) – since in biology “Kingdom” is the second highest taxonomic rank, just after “Domain”. We will present some principles to help writing not-database-centric code, without being bloated by all the DDD requirements.
Let your Kingdom come!
High Performance Object Pascal Code on Servers (at EKON 22)Arnaud Bouchez
This EKON 22 conference is about high performance on servers, written in the object pascal (Delphi / FPC) language. Profiling should be the first step to avoid premature optimization, which is the root of all evil (Knuth). But when some bottlenecks are identified, we introduce some simple architecture patterns (like caching or microservices), data structures and algorithms to make process actually faster, with minimal refactoring. It was a fun session about how to write faster code, ending up by looking at the Delphi CPU view – even if you don’t know assembly.
This EKON 22 conference was not about the code formatting - where we put the “begin” keyword is mostly a matter of taste and convention. But it shows how the object pascal strong typing system, and its language expressiveness may help writing clean(er) code. Abstract SOLID principles could help define the class and services hierarchy. After years of server-side coding, we propose some practical guidelines for cleaner object pascal programming, to reduce technical debt, and allow cross-platform/cross-compiler support.
Server side process does react to business events. User actions, timers, other services may trigger states of change, which should be tracked and propagated. A classical implementation is to define a shared database or centralized message queue, locally or in the cloud. When applied to Microservices, this monolithic approach will quickly appear as a limitation.
In this session, we will introduce how Microservices could have their own dedicated persistence layer (i.e. database), and how real-time callbacks could be used to leverage real-time propagation of events, without any centralized message queue. Both ORM and SOA features of the Open Source mORMot framework will illustrate how to write such stand-alone services.
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Globus
Large Language Models (LLMs) are currently the center of attention in the tech world, particularly for their potential to advance research. In this presentation, we'll explore a straightforward and effective method for quickly initiating inference runs on supercomputers using the vLLM tool with Globus Compute, specifically on the Polaris system at ALCF. We'll begin by briefly discussing the popularity and applications of LLMs in various fields. Following this, we will introduce the vLLM tool, and explain how it integrates with Globus Compute to efficiently manage LLM operations on Polaris. Attendees will learn the practical aspects of setting up and remotely triggering LLMs from local machines, focusing on ease of use and efficiency. This talk is ideal for researchers and practitioners looking to leverage the power of LLMs in their work, offering a clear guide to harnessing supercomputing resources for quick and effective LLM inference.
Quarkus Hidden and Forbidden ExtensionsMax Andersen
Quarkus has a vast extension ecosystem and is known for its subsonic and subatomic feature set. Some of these features are not as well known, and some extensions are less talked about, but that does not make them less interesting - quite the opposite.
Come join this talk to see some tips and tricks for using Quarkus and some of the lesser known features, extensions and development techniques.
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisGlobus
JASMIN is the UK’s high-performance data analysis platform for environmental science, operated by STFC on behalf of the UK Natural Environment Research Council (NERC). In addition to its role in hosting the CEDA Archive (NERC’s long-term repository for climate, atmospheric science & Earth observation data in the UK), JASMIN provides a collaborative platform to a community of around 2,000 scientists in the UK and beyond, providing nearly 400 environmental science projects with working space, compute resources and tools to facilitate their work. High-performance data transfer into and out of JASMIN has always been a key feature, with many scientists bringing model outputs from supercomputers elsewhere in the UK, to analyse against observational or other model data in the CEDA Archive. A growing number of JASMIN users are now realising the benefits of using the Globus service to provide reliable and efficient data movement and other tasks in this and other contexts. Further use cases involve long-distance (intercontinental) transfers to and from JASMIN, and collecting results from a mobile atmospheric radar system, pushing data to JASMIN via a lightweight Globus deployment. We provide details of how Globus fits into our current infrastructure, our experience of the recent migration to GCSv5.4, and of our interest in developing use of the wider ecosystem of Globus services for the benefit of our user community.
SOCRadar Research Team: Latest Activities of IntelBrokerSOCRadar
The European Union Agency for Law Enforcement Cooperation (Europol) has suffered an alleged data breach after a notorious threat actor claimed to have exfiltrated data from its systems. Infamous data leaker IntelBroker posted on the even more infamous BreachForums hacking forum, saying that Europol suffered a data breach this month.
The alleged breach affected Europol agencies CCSE, EC3, Europol Platform for Experts, Law Enforcement Forum, and SIRIUS. Infiltration of these entities can disrupt ongoing investigations and compromise sensitive intelligence shared among international law enforcement agencies.
However, this is neither the first nor the last activity of IntekBroker. We have compiled for you what happened in the last few days. To track such hacker activities on dark web sources like hacker forums, private Telegram channels, and other hidden platforms where cyber threats often originate, you can check SOCRadar’s Dark Web News.
Stay Informed on Threat Actors’ Activity on the Dark Web with SOCRadar!
First Steps with Globus Compute Multi-User EndpointsGlobus
In this presentation we will share our experiences around getting started with the Globus Compute multi-user endpoint. Working with the Pharmacology group at the University of Auckland, we have previously written an application using Globus Compute that can offload computationally expensive steps in the researcher's workflows, which they wish to manage from their familiar Windows environments, onto the NeSI (New Zealand eScience Infrastructure) cluster. Some of the challenges we have encountered were that each researcher had to set up and manage their own single-user globus compute endpoint and that the workloads had varying resource requirements (CPUs, memory and wall time) between different runs. We hope that the multi-user endpoint will help to address these challenges and share an update on our progress here.
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxrickgrimesss22
Discover the essential features to incorporate in your Winzo clone app to boost business growth, enhance user engagement, and drive revenue. Learn how to create a compelling gaming experience that stands out in the competitive market.
Listen to the keynote address and hear about the latest developments from Rachana Ananthakrishnan and Ian Foster who review the updates to the Globus Platform and Service, and the relevance of Globus to the scientific community as an automation platform to accelerate scientific discovery.
Understanding Globus Data Transfers with NetSageGlobus
NetSage is an open privacy-aware network measurement, analysis, and visualization service designed to help end-users visualize and reason about large data transfers. NetSage traditionally has used a combination of passive measurements, including SNMP and flow data, as well as active measurements, mainly perfSONAR, to provide longitudinal network performance data visualization. It has been deployed by dozens of networks world wide, and is supported domestically by the Engagement and Performance Operations Center (EPOC), NSF #2328479. We have recently expanded the NetSage data sources to include logs for Globus data transfers, following the same privacy-preserving approach as for Flow data. Using the logs for the Texas Advanced Computing Center (TACC) as an example, this talk will walk through several different example use cases that NetSage can answer, including: Who is using Globus to share data with my institution, and what kind of performance are they able to achieve? How many transfers has Globus supported for us? Which sites are we sharing the most data with, and how is that changing over time? How is my site using Globus to move data internally, and what kind of performance do we see for those transfers? What percentage of data transfers at my institution used Globus, and how did the overall data transfer performance compare to the Globus users?
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTier1 app
Even though at surface level ‘java.lang.OutOfMemoryError’ appears as one single error; underlyingly there are 9 types of OutOfMemoryError. Each type of OutOfMemoryError has different causes, diagnosis approaches and solutions. This session equips you with the knowledge, tools, and techniques needed to troubleshoot and conquer OutOfMemoryError in all its forms, ensuring smoother, more efficient Java applications.
In software engineering, the right architecture is essential for robust, scalable platforms. Wix has undergone a pivotal shift from event sourcing to a CRUD-based model for its microservices. This talk will chart the course of this pivotal journey.
Event sourcing, which records state changes as immutable events, provided robust auditing and "time travel" debugging for Wix Stores' microservices. Despite its benefits, the complexity it introduced in state management slowed development. Wix responded by adopting a simpler, unified CRUD model. This talk will explore the challenges of event sourcing and the advantages of Wix's new "CRUD on steroids" approach, which streamlines API integration and domain event management while preserving data integrity and system resilience.
Participants will gain valuable insights into Wix's strategies for ensuring atomicity in database updates and event production, as well as caching, materialization, and performance optimization techniques within a distributed system.
Join us to discover how Wix has mastered the art of balancing simplicity and extensibility, and learn how the re-adoption of the modest CRUD has turbocharged their development velocity, resilience, and scalability in a high-growth environment.
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...informapgpstrackings
Keep tabs on your field staff effortlessly with Informap Technology Centre LLC. Real-time tracking, task assignment, and smart features for efficient management. Request a live demo today!
For more details, visit us : https://informapuae.com/field-staff-tracking/
Unleash Unlimited Potential with One-Time Purchase
BoxLang is more than just a language; it's a community. By choosing a Visionary License, you're not just investing in your success, you're actively contributing to the ongoing development and support of BoxLang.
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdfJay Das
With the advent of artificial intelligence or AI tools, project management processes are undergoing a transformative shift. By using tools like ChatGPT, and Bard organizations can empower their leaders and managers to plan, execute, and monitor projects more effectively.
Software Engineering, Software Consulting, Tech Lead.
Spring Boot, Spring Cloud, Spring Core, Spring JDBC, Spring Security,
Spring Transaction, Spring MVC,
Log4j, REST/SOAP WEB-SERVICES.
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Anthony Dahanne
Les Buildpacks existent depuis plus de 10 ans ! D’abord, ils étaient utilisés pour détecter et construire une application avant de la déployer sur certains PaaS. Ensuite, nous avons pu créer des images Docker (OCI) avec leur dernière génération, les Cloud Native Buildpacks (CNCF en incubation). Sont-ils une bonne alternative au Dockerfile ? Que sont les buildpacks Paketo ? Quelles communautés les soutiennent et comment ?
Venez le découvrir lors de cette session ignite
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
D1 from interfaces to solid
1. Software Architecture & Design
Architecture
From n-Tier to SOA
From SOAP to REST
Technical Debt
Design
From SQL to ORM, NoSQL and ODM
From RAD to MVC
SOLID principles
Domain Driven Design (DDD)
Applying patterns on Delphi code using mORMot
Software Architecture & Design
3. From Interfaces to SOLID
Delphi and interfaces
SOLID design principles
Dependency Injection, stubs and mocks
Using mORMot features
Delphi and Weak pointers
From Interfaces to SOLID
4. Delphi and interfaces
In Delphi OOP model
An interface defines a type
that comprises abstract virtual methods
It is a declaration of functionality
without an implementation of that functionality
It defines "what" is available,
not "how" it is made available
From Interfaces to SOLID
5. Delphi and interfaces
Declaring an interface
Naming convention: ICalculator
No visibility attribute: all published
No fields, just methods and properties
Unique identifier by GUID (Ctrl Shift G)
From Interfaces to SOLID
type
ICalculator = interface(IInvokable)
['{9A60C8ED-CEB2-4E09-87D4-4A16F496E5FE}']
/// add two signed 32 bit integers
function Add(n1,n2: integer): integer;
end;
6. Delphi and interfaces
Implementing an interface
ICalculator added to the “inheritance chain”
TCalculator implements a behavior
From Interfaces to SOLID
type
TServiceCalculator = class(TInterfacedObject, ICalculator)
protected
fBulk: string;
public
function Add(n1,n2: integer): integer;
procedure SetBulk(const aValue: string);
end;
function TServiceCalculator.Add(n1, n2: integer): integer;
begin
result := n1+n2;
end;
procedure TServiceCalculator.SetBulk(const aValue: string);
begin
fBulk := aValue;
end;
7. Delphi and interfaces
Using an interface
Strong typing
The variable defines a behavior (contract)
Path to abstraction
From Interfaces to SOLID
function MyAdd(a,b: integer): integer;
var Calculator: ICalculator;
begin
Calculator := TServiceCalculator.Create;
result := Calculator.Add(a,b);
end;
8. Delphi and interfaces
Using an interface
Strong typing
The variable defines a behavior (contract)
Path to abstraction
Automatic try..finally
From Interfaces to SOLID
function MyAdd(a,b: integer): integer;
var Calculator: TServiceCalculator;
begin
Calculator := TServiceCalculator.Create;
try
result := Calculator.Add(a,b);
finally
Calculator.Free;
end;
end;
function MyAdd(a,b: integer): integer;
var Calculator: ICalculator;
begin
Calculator := TServiceCalculator.Create;
result := Calculator.Add(a,b);
end;
9. Delphi and interfaces
Automatic try..finally
Compiler generates
some hidden code…
Behavior inherited from TInterfacedObject
Similar to COM / ActiveX
From Interfaces to SOLID
function MyAdd(a,b: integer): integer;
var Calculator: ICalculator;
begin
Calculator := TServiceCalculator.Create;
result := Calculator.Add(a,b);
end;
function MyAdd(a,b: integer): integer;
var Calculator: TServiceCalculator;
begin
Calculator := nil;
Calculator := TServiceCalculator.Create;
try
Calculator.FRefCount := 1;
result := Calculator.Add(a,b);
finally
dec(Calculator.FRefCount);
if Calculator.FRefCount=0 then
Calculator.Free;
end;
end;
10. Delphi and interfaces
Interfaces are orthogonal to implementation
There is more than one way to do it
From Interfaces to SOLID
type
TOtherServiceCalculator = class(TInterfacedObject, ICalculator)
protected
function Add(n1,n2: integer): integer;
end;
function TOtherServiceCalculator.Add(n1, n2: integer): integer;
begin
result := n2+n1;
end;
function MyOtherAdd(a,b: integer): integer;
var Calculator: ICalculator;
begin
ICalculator := TOtherServiceCalculator.Create;
result := Calculator.Add(a,b);
end;
11. SOLID design principles
Single responsibility principle
Open/closed principle
Liskov substitution principle (design by contract)
Interface segregation principle
Dependency inversion principle
From Interfaces to SOLID
12. SOLID design principles
Single responsibility
Object should have only a single responsibility
Open/closed
Entities should be open for extension,
but closed for modification
Liskov substitution (design by contract)
Objects should be replaceable with instances of their
subtypes without altering the correctness of that program
Interface segregation
Many specific interfaces are better than one
Dependency inversion
Depend upon abstractions, not depend upon concretions
From Interfaces to SOLID
13. SOLID design principles
Help to fight well-known weaknesses
Rigidity
Hard to change something because every change
affects too many other parts of the system
Fragility
When you make a change, unexpected parts of the
system break
Immobility
Hard to reuse in another application because it cannot
be disentangled from the current application
From Interfaces to SOLID
14. SOLID design principles
Single Responsibility
When you define a class, it shall be designed to
implement only one feature
The so-called feature can be seen as
an "axis of change" or a "a reason for change"
From Interfaces to SOLID
15. SOLID design principles
Single Responsibility
One class shall have only one reason
that justifies changing its implementation
Classes shall have few dependencies
on other classes
Classes shall be abstracted
from the particular layer they are running
From Interfaces to SOLID
16. SOLID design principles
Single Responsibility
Splitting classes
Imagine a TBarCodeScanner class
to handle a serial bar-code scanner
Later on, we want to implement USB support
First idea may be to inherit
From Interfaces to SOLID
17. SOLID design principles
Single Responsibility
Splitting classes
Imagine a TBarCodeScanner class
to handle a serial bar-code scanner
Later on, we want to implement USB support
But we would rather split the class hierarchy
From Interfaces to SOLID
18. SOLID design principles
Single Responsibility
Splitting classes
Later on, the manufacturer updates its protocol
To add new features, e.g. 3D scanning or coffee making
How do we implement this?
We have two “axis of change”
so we would define two classes
From Interfaces to SOLID
19. SOLID design principles
Single Responsibility
Splitting classes
Later on, the manufacturer updates its protocol
To add new features, e.g. 3D scanning or coffee making
We defined two classes, which will be joined/composed
in actual barcode scanner classes
From Interfaces to SOLID
20. SOLID design principles
Single Responsibility
Splitting classes
TAbstractBarcodeScanner = class(TComponent)
protected
fProtocol: TAbstractBarcodeProtocol;
fConnection: AbstractBarcodeConnection;
...
constructor TSerialBarCodeScanner.Create(
const aComPort: string; aBitRate: integer);
begin
fConnection := TSerialBarcodeConnection(aComPort,aBitRate);
fProtocol := TBCP1BarcodeProtocol.Create(fConnection);
end;
From Interfaces to SOLID
21. SOLID design principles
Single Responsibility
Another example
from SynDB class definitions:
TSQLDBConnectionProperties
TSQLDBConnection
TSQLDBStatement
Each class has its own purpose,
and axis of change
And could be implemented via ODBC, OleDB,
direct client access…
From Interfaces to SOLID
22. SOLID design principles
Single Responsibility
Do not mix GUI and logic
Do not mix logic and database
Do not couple your code to an OS
Check your uses statement
There should be no reference to the UI
(e.g. Dialogs) in your business class
No dependency to DB libraries (this is a hard one)
No reference to WinAPI.Windows
From Interfaces to SOLID
23. SOLID design principles
Single Responsibility
Code smells
When abusing of:
FreeAndNil()
{$ifdef} … {$endif}
uses unit1, unit2, unit3, … unit1000;
When you can’t find the right method in a class
(mORMot may need some refactoring here)
When unitary tests are hard to write
From Interfaces to SOLID
24. SOLID design principles
Open / Close principle
When you define a class or an interface
it shall be open for extension
but closed for modification
From Interfaces to SOLID
25. SOLID design principles
Open / Closed principle
Open for extension
Abstract class is overridden by implementations
No singleton nor global variable – ever
Rely on abstraction
if aObject is aClass then … it stinks!
Closed for modification
E.g. via explicitly protected or private members
RTTI is dangerous: it may open the closed door
From Interfaces to SOLID
26. SOLID design principles
Open / Closed principle
In practice
Define meaningful interface types
Following the Design By Contract principle
Define Value objects (DTOs) to transfer the data
With almost no methods, but for initialization
With public members, to access the value
Define Process objects to modify the data
With public methods, abstracted in the interface
With mostly private members
From Interfaces to SOLID
27. SOLID design principles
Open / Close principle
type
TAbstractBarcodeScanner = class(TComponent)
protected
fProtocol: TAbstractBarcodeProtocol;
fConnection: AbstractBarcodeConnection;
public
property Protocol: TAbstractBarcodeProtocol read fProtocol;
property Connection: AbstractBarcodeConnection read fConnection;
...
Protocol and Connection are read/only
They are injected by the overridden class constructor
So it will be Open for extension
From Interfaces to SOLID
28. SOLID design principles
Open / Close principle
type
TAbstractBarcodeScanner = class(TComponent)
protected
fProtocol: TAbstractBarcodeProtocol;
fConnection: AbstractBarcodeConnection;
public
property Protocol: TAbstractBarcodeProtocol read fProtocol;
property Connection: AbstractBarcodeConnection read fConnection;
...
Protocol and Connection are read/only
You could not change the behavior of a class
It is Closed for modification
From Interfaces to SOLID
31. SOLID design principles
Liskov substitution principle
If TChild is a subtype of TParent
then objects of type TParent
may be replaced with objects of type TChild
without altering any of the desirable properties
of that program (correctness, task performed, etc.)
From Interfaces to SOLID
32. SOLID design principles
Liskov substitution principle
Tied to the Open / Closed principle
If you define a child, you should not modify the parent
Code-reusability of the parent implementation
You will be able
to stub or mock an interface or a class
Allow correct testing of a whole system:
even if all single unit tests did pass,
real system may not work if this principle was broken
From Interfaces to SOLID
33. SOLID design principles
Liskov substitution patterns
Design by contract
Meyer's (Eiffel language) rule:
“when redefining a routine [in a derivative],
you may only replace its precondition by a weaker
one, and its postcondition by a stronger one”
Define assertions at method level:
What does it expect, guarantee, and maintain?
About input/output values or types, side effects,
invariants, errors/exceptions, performance…
From Interfaces to SOLID
34. SOLID design principles
Liskov substitution patterns
Write your code using abstract variables
Rely on parents methods and properties
Use interface variables
instead of class implementation
Uncouple dependencies via class composition
From Interfaces to SOLID
35. SOLID design principles
Liskov substitution patterns
Factory pattern
In strongly typed languages (Java, C#, Delphi),
the factory is the class/object type and its constructor
Repository pattern
Allow persistence agnosticism (e.g. via ORM)
Service locator pattern
Get a class instance implementing a given interface
According to the given context (no global/singleton)
From Interfaces to SOLID
36. SOLID design principles
Liskov substitution patterns
Practical, not dogmatic LSP
“Parent” and “Child” are not absolute
Depending on the context, you may define a given level
as the “highest” LSP abstract class
e.g. if you work on server side, you may need some
server-only properties and methods
LSP idea is to be consistent,
once the abstraction level is defined
From Interfaces to SOLID
37. SOLID design principles
Liskov substitution patterns
Practical, not dogmatic LSP
“Parent” and “Child” are not absolute
Inheritance is often used as code sharing among classes,
not as an abstraction contract
In this context, LSP may not apply at class level:
be pragmatic, and write efficient code
But LSP may apply at interface level,
for a set of methods implemented by the class
From Interfaces to SOLID
38. SOLID design principles
Liskov substitution code smells
if aObject is aClass then …
case aObject.EnumeratedType of …
function … abstract;
without further override;
unit parent;
uses child1,child2,child3;
From Interfaces to SOLID
39. SOLID design principles
Interface segregation principle
Once an interface has become too 'fat'
it shall be split into smaller
and more specific interfaces
so that any clients of the interface will only know
about the methods that pertain to them
In a nutshell, no client should be forced
to depend on methods it does not use
From Interfaces to SOLID
40. SOLID design principles
Interface segregation principle
Smaller dedicated classes should be preferred
Single Responsibility Principle
Favor composition over inheritance
Smaller dedicated interfaces
Gather operations/methods per context
Meaningful naming and conventions
So that the contract would be easier to understand
From Interfaces to SOLID
41. SOLID design principles
Interface segregation principle
Perfectly fits the SOA uncoupling pattern
Stateless MicroServices for horizontal scaling
Allows to release memory and resources ASAP
Smaller objects have more bounded dependencies
Ease unit testing
Less coverage
Less coupling
From Interfaces to SOLID
42. SOLID design principles
Interface segregation principle
Excludes RAD
Logic implemented in TForm TDataModule
where methods are procedural code in disguise
Put your logic behind interfaces
and call them from your UI (over VCL and FMX)
Favors DDD
Segregation avoid domain leaking
Dedicated interfaces, e.g. for third party consumption
From Interfaces to SOLID
43. SOLID design principles
Dependency Inversion
High-level modules
should not depend on low-level modules
Both should depend on abstractions
Following other SOLI principles
Abstractions should not depend upon details
Details should depend upon abstractions
Business Logic should not depend on database
Application Layer should not depend on client UI techno
From Interfaces to SOLID
44. SOLID design principles
Dependency Inversion
In most conventional programming style:
You write low-level components (e.g. DB tables)
Then you integrate them with high-level components
But this limits the re-use of high-level code
In fact, it breaks the Liskov substitution principle
It reduces the testing abilities (e.g. need of a real DB)
From Interfaces to SOLID
45. SOLID design principles
Dependency Inversion may be implemented
Via a plug-in system
e.g. external libraries (for embedded applications)
Using a service locator
e.g. SOA catalog (SaaS/cloud)
class resolution from an interface type
From Interfaces to SOLID
46. SOLID design principles
Dependency Inversion may be implemented
Via Dependency Injection
Concretions are injected to the objects using them
Only abstractions are known at design/coding time
Uncoupled implementation injected at runtime
Modular coding
Perfect for bigger/complex projects, with a set of teams
Ease testing, via stub/mock dependencies injection
e.g. a fake database, defined as a Repository service
Scaling abilities
From Interfaces to SOLID
47. SOLID design principles
Dependency Inversion may be implemented
Via Dependency Injection
A class will define its dependencies as read-only
interface members
Implementation will be injected at constructor level
via explicit constructor parameters
via automated resolution via RTTI
via service locator/resolver
From Interfaces to SOLID
48. DI, Stubs and Mocks
Thanks to SOLID design principles
All your code logic will now be abstracted
to the implementation underneath
But you need to inject the implementation
This is Dependency Injection purpose
You can also create fake instances to implement
a given interface, and enhance testing
Introducing Stubs and Mocks
From Interfaces to SOLID
49. DI, Stubs and Mocks
Dependency Injection
Define external dependencies as interface
as (private / protected) read-only members
To set the implementation instance:
Either inject the interfaces as constructor parameters
Or use a Factory / Service locator
From Interfaces to SOLID
50. DI, Stubs and Mocks
Dependency Injection
Purpose is to test the following class:
From Interfaces to SOLID
TLoginController = class(TInterfacedObject,ILoginController)
protected
fUserRepository: IUserRepository;
fSmsSender: ISmsSender;
public
constructor Create(const aUserRepository: IUserRepository;
const aSmsSender: ISmsSender);
procedure ForgotMyPassword(const UserName: RawUTF8);
end;
constructor TLoginController.Create(const aUserRepository: IUserRepository;
const aSmsSender: ISmsSender);
begin
fUserRepository := aUserRepository;
fSmsSender := aSmsSender;
end;
51. DI, Stubs and Mocks
Dependency Injection
Dependencies are defined as
Two small, uncoupled, SOLID task-specific interfaces
From Interfaces to SOLID
IUserRepository = interface(IInvokable)
['{B21E5B21-28F4-4874-8446-BD0B06DAA07F}']
function GetUserByName(const Name: RawUTF8): TUser;
procedure Save(const User: TUser);
end;
ISmsSender = interface(IInvokable)
['{8F87CB56-5E2F-437E-B2E6-B3020835DC61}']
function Send(const Text, Number: RawUTF8): boolean;
end;
52. DI, Stubs and Mocks
Dependency Injection
Using a dedicated Data Transfer Object (DTO)
No dependency against storage, nor other classes
From Interfaces to SOLID
IUserRepository = interface(IInvokable)
['{B21E5B21-28F4-4874-8446-BD0B06DAA07F}']
function GetUserByName(const Name: RawUTF8): TUser;
procedure Save(const User: TUser);
end;
TUser = record
Name: RawUTF8;
Password: RawUTF8;
MobilePhoneNumber: RawUTF8;
ID: Integer;
end;
53. DI, Stubs and Mocks
Dependency Injection
The high-level method to be tested:
Open/Closed, Liskov and mainly Dependency
Inversion principles are followed
Will we need a full database and to send a SMS?
From Interfaces to SOLID
procedure TLoginController.ForgotMyPassword(const UserName: RawUTF8);
var U: TUser;
begin
U := fUserRepository.GetUserByName(UserName);
U.Password := Int32ToUtf8(Random(MaxInt));
if fSmsSender.Send('Your new password is '+U.Password,U.MobilePhoneNumber) then
fUserRepository.Save(U);
end;
54. DI, Stubs and Mocks
"The Art of Unit Testing" (Osherove, Roy - 2009)
Stubs are fake objects
implementing a given contract
and returning pre-arranged responses
They just let the test pass
They “emulate” some behavior (e.g. a database)
From Interfaces to SOLID
55. DI, Stubs and Mocks
"The Art of Unit Testing" (Osherove, Roy - 2009)
Mocks are fake objects like stubs
which will verify if an interaction occurred or not
They help decide if a test failed or passed
There should be only one mock per test
From Interfaces to SOLID
57. DI, Stubs and Mocks
Expect – Run – Verify pattern
From Interfaces to SOLID
procedure TMyTest.ForgotMyPassword;
var SmsSender: ISmsSender;
UserRepository: IUserRepository;
begin
TInterfaceStub.Create(ISmsSender,SmsSender).
Returns('Send',[true]);
TInterfaceMock.Create(IUserRepository,UserRepository,self).
ExpectsCount('Save',qoEqualTo,1);
with TLoginController.Create(UserRepository,SmsSender) do
try
ForgotMyPassword('toto');
finally
Free;
end;
end;
58. DI, Stubs and Mocks
Expect – Run – Verify pattern
TInterfaceStub / TInterfaceMock constructors
are in fact Factories for any interface
Clear distinction between stub and mock
Mock is linked to its test case (self: TMyTest)
From Interfaces to SOLID
procedure TMyTest.ForgotMyPassword;
var SmsSender: ISmsSender;
UserRepository: IUserRepository;
begin
TInterfaceStub.Create(ISmsSender,SmsSender).
Returns('Send',[true]);
TInterfaceMock.Create(IUserRepository,UserRepository,self).
ExpectsCount('Save',qoEqualTo,1);
59. DI, Stubs and Mocks
Expect – Run – Verify pattern
Execution code itself sounds like real-life code
But all dependencies have been injected
Stubs will emulate real behavior
Mock will verify that all expectations are fulfilled
From Interfaces to SOLID
with TLoginController.Create(UserRepository,SmsSender) do
try
ForgotMyPassword('toto');
finally
Free;
end;
end;
60. DI, Stubs and Mocks
Expect – Run – Verify pattern
From Interfaces to SOLID
procedure TMyTest.ForgotMyPassword;
var SmsSender: ISmsSender;
UserRepository: IUserRepository;
begin
TInterfaceStub.Create(ISmsSender,SmsSender).
Returns('Send',[true]);
TInterfaceMock.Create(IUserRepository,UserRepository,self).
ExpectsCount('Save',qoEqualTo,1);
with TLoginController.Create(UserRepository,SmsSender) do
try
ForgotMyPassword('toto');
finally
Free;
end;
end;
61. DI, Stubs and Mocks
Run – Verify (aka “Test spy”) pattern
From Interfaces to SOLID
procedure TMyTest.ForgotMyPassword;
var SmsSender: ISmsSender;
UserRepository: IUserRepository;
Spy: TInterfaceMockSpy;
begin
TInterfaceStub.Create(ISmsSender,SmsSender).
Returns('Send',[true]);
Spy := TInterfaceMockSpy.Create(IUserRepository,UserRepository,self);
with TLoginController.Create(UserRepository,SmsSender) do
try
ForgotMyPassword('toto');
finally
Free;
end;
Spy.Verify('Save');
end;
62. DI, Stubs and Mocks
Another features:
Return complex values (e.g. a DTO)
Use a delegate to create a stub/mock
Using named or indexed variant parameters
Using JSON array of values
Access the test case when mocking
Trace and verify the calls
With a fluent interface
Log all calls (as JSON)
From Interfaces to SOLID
63. DI, Stubs and Mocks
Dependency Injection
Inheriting from TInjectableObject
type
TServiceToBeTested = class(TInjectableObject,IServiceToBeTested)
protected
fService: IInjectedService;
published
property Service: IInjectedService read fService;
end;
Will auto-inject interface published properties
At instance creation
Handled by TSQLRest.Services
From Interfaces to SOLID
64. DI, Stubs and Mocks
Dependency Injection
Inheriting from TInjectableObject
var Test: IServiceToBeTested;
begin
Test := TServiceToBeTested.CreateInjected(
[ICalculator],
[TInterfaceMock.Create(IPersistence,self).
ExpectsCount('SaveItem',qoEqualTo,1),
RestInstance.Services],
[AnyInterfacedObject]);
...
From Interfaces to SOLID
65. DI, Stubs and Mocks
Dependency Injection
Inheriting from TInjectableObject
procedure TServiceToBeTested.AnyProcessMethod;
var Service: IInjectedService;
begin
Resolve(IInjectedService,Service);
Service.DoSomething;
end;
From Interfaces to SOLID
66. DI, Stubs and Mocks
Dependency Injection
Inheriting from TInjectableAutoCreateFields
type
TServiceToBeTested = class(TInjectableObjectAutoCreateFields,
IServiceToBeTested)
protected
fService: IInjectedService;
fNestedObject: TSynPersistentValue;
published
property Service: IInjectedService read fService;
property NestedObject: TSynPersistentValue read fNestedObject;
end;
Will auto-define published properties
Resolve interface services
Create TPersistent TSynPersistent TAutoCreateField
From Interfaces to SOLID
67. Weak references
Delphi type reference model
class
as weak references (plain pointer) and explicit Free
with TComponent ownership for the VCL/FMX
integer Int64 currency double record
widestring variant
with explicit copy
string or any dynamic array
via copy-on-write (COW) with reference counting
interface
as strong reference with reference counting
From Interfaces to SOLID
68. Weak references
Strong reference-counted types (OLE/ COM)
Will increase the count at assignment
And decrease the count at owner’s release
When the count reaches 0, release the instance
Issue comes when there are
Circular references
External list(s) of references
From Interfaces to SOLID
69. Weak references
Managed languages (C# or Java)
Will let the Garbage Collector handle
interface variable life time
This is complex and resource consuming
But easy to work with
Unmanaged languages (Delphi or ObjectiveC)
Need explicit weak reference behavior
mORMot features zeroing weak pointers
Like Apple’s ARC model
From Interfaces to SOLID
70. Weak references
Zeroing weak pointers
From Interfaces to SOLID
IParent = interface
procedure SetChild(const Value: IChild);
function GetChild: IChild;
function HasChild: boolean;
property Child: IChild read GetChild write SetChild;
end;
IChild = interface
procedure SetParent(const Value: IParent);
function GetParent: IParent;
property Parent: IParent read GetParent write SetParent;
end;
71. Weak references
Zeroing weak pointers
This code will leak memory
From Interfaces to SOLID
IParent = interface
procedure SetChild(const Value: IChild);
function GetChild: IChild;
function HasChild: boolean;
property Child: IChild read GetChild write SetChild;
end;
IChild = interface
procedure SetParent(const Value: IParent);
function GetParent: IParent;
property Parent: IParent read GetParent write SetParent;
end;
procedure TParent.SetChild(const Value: IChild);
begin
FChild := Value;
end;
procedure TChild.SetParent(const Value: IParent);
begin
FParent := Value;
end;
72. Weak references
Zeroing weak pointers
This code won’t leak memory
FChild and FParent will be set to nil
when the stored instance will be freed
From Interfaces to SOLID
IParent = interface
procedure SetChild(const Value: IChild);
function GetChild: IChild;
function HasChild: boolean;
property Child: IChild read GetChild write SetChild;
end;
IChild = interface
procedure SetParent(const Value: IParent);
function GetParent: IParent;
property Parent: IParent read GetParent write SetParent;
end;
procedure TParent.SetChild(const Value: IChild);
begin
SetWeakZero(self,@FChild,Value);
end;
procedure TChild.SetParent(const Value: IParent);
begin
SetWeakZero(self,@FParent,Value);
end;
73. Weak references
Delphi NextGen memory model
Uses ARC for every TObject instance
This is transparent for TComponent / FMX
No try … finally Free block needed
But breaks the proven weak reference model
and a lot of existing code
Only UTF-16 string type
Direct 8 bit string type disabled
UTF8String RawByteString back in 10.1 Berlin
From Interfaces to SOLID