SOLID - a set of concepts for designing maintainable and understandable software - yet some of these ideas can be hard to understand themselves. Scholarly definitions and generic examples of these are often still confusing and not applicable to real world applications. By taking a look at an actual application, we'll explore these principles in action, and demonstrate the benefits of following them.
SOLID – a set of concepts for designing maintainable and understandable software – yet some of these ideas can be hard to understand themselves. Scholarly definitions and generic examples of these are often still confusing and not applicable to real world applications. By taking a look at an actual application, we’ll explore these principles in action, and demonstrate the benefits of following them.
Hacking Your Way To Better Security - Dutch PHP Conference 2016Colin O'Dell
The goal of this talk is to educate developers on common security vulnerabilities, how they are exploited, and how to protect against them. We'll explore several of the OWASP Top 10 attack vectors like SQL injection, XSS, CSRF, session hijacking, and insecure direct object references. Each topic will be approached from the perspective of an attacker to see how these vulnerabilities are detected and exploited using several realistic examples. Once we've established an understanding of how these attacks work, we'll look at concrete steps you can take to secure web applications against such vulnerabilities. The knowledge gained from this talk can also be used for participating in "Capture the Flag" security competitions.
All projects start with a lot of enthusiasm. As many projects grow the technical debt gets bigger and the enthusiasm gets less. Almost any developer can develop a great project, but the key is maintaining an ever evolving application with minimal technical debt without loosing enthusiasm.
During this talk you will be taken on the journey of application design. The starting point is an application that looks fine but contains lots of potential pitfalls. We will address the problems and solve them with beautiful design. We end up with testable, nicely separated software with a clear intention.
Un gioco in cui vincono tutti o due piccioni con una fava ;)
Lavorare rivolti alla creazione di valore per il cliente e da questo ottenere una libreria quasi pronta per essere pubblicata
Value objects express “‘what’ something is rather than ‘who’ or ‘which’ it is.” In other words, values lack identity.
For example, the number 10 or the color red - all instances of 10 are conceptually equal to all other instances of 10, and likewise, red is always red. Two red bikes, however, have distinct identities.
We’ll explore how extracting value objects can simplify the challenge of bringing the real-world to bear as software. Then, we’ll touch on some strategies for integrating value objects with everyone’s favorite ORM, ActiveRecord.
SOLID – a set of concepts for designing maintainable and understandable software – yet some of these ideas can be hard to understand themselves. Scholarly definitions and generic examples of these are often still confusing and not applicable to real world applications. By taking a look at an actual application, we’ll explore these principles in action, and demonstrate the benefits of following them.
Hacking Your Way To Better Security - Dutch PHP Conference 2016Colin O'Dell
The goal of this talk is to educate developers on common security vulnerabilities, how they are exploited, and how to protect against them. We'll explore several of the OWASP Top 10 attack vectors like SQL injection, XSS, CSRF, session hijacking, and insecure direct object references. Each topic will be approached from the perspective of an attacker to see how these vulnerabilities are detected and exploited using several realistic examples. Once we've established an understanding of how these attacks work, we'll look at concrete steps you can take to secure web applications against such vulnerabilities. The knowledge gained from this talk can also be used for participating in "Capture the Flag" security competitions.
All projects start with a lot of enthusiasm. As many projects grow the technical debt gets bigger and the enthusiasm gets less. Almost any developer can develop a great project, but the key is maintaining an ever evolving application with minimal technical debt without loosing enthusiasm.
During this talk you will be taken on the journey of application design. The starting point is an application that looks fine but contains lots of potential pitfalls. We will address the problems and solve them with beautiful design. We end up with testable, nicely separated software with a clear intention.
Un gioco in cui vincono tutti o due piccioni con una fava ;)
Lavorare rivolti alla creazione di valore per il cliente e da questo ottenere una libreria quasi pronta per essere pubblicata
Value objects express “‘what’ something is rather than ‘who’ or ‘which’ it is.” In other words, values lack identity.
For example, the number 10 or the color red - all instances of 10 are conceptually equal to all other instances of 10, and likewise, red is always red. Two red bikes, however, have distinct identities.
We’ll explore how extracting value objects can simplify the challenge of bringing the real-world to bear as software. Then, we’ll touch on some strategies for integrating value objects with everyone’s favorite ORM, ActiveRecord.
Type safe embedded domain-specific languagesArthur Xavier
Language is everything; it governs our lives: from our thought processes, our communication abilities and our understanding of the world, all the way up to law, politics, logic and programming. All of these domains of human experience are governed by different languages that talk to each other, and so should be your code. Haskell provides all the means necessary—and many more—to easily and safely use embedded small languages that are tailored to specific needs and business domains.
In this series of lectures and workshops, we will explore the whats, whys and hows of embedded domain-specific languages in Haskell, and how language oriented programing can bring type-safety, composability and simplicity to the development of complex applications.
Adding Dependency Injection to Legacy ApplicationsSam Hennessy
Dependency Injection (DI) is a fantastic technique, but what if you what to use dependency injection in your legacy application. Fear not! As someone who as done this very thing, I will show how you can successful and incrementally add DI to any application. I will present a number of recipes and solutions to common problems and give a tour of the various PHP DI projects and how they can help.
Devs for Leokz e 7Masters - WTF Oriented ProgrammingFabio Akita
Apresentação que fiz tanto no evento online beneficente Devs for Leokz (https://www.eventials.com/eduardo.shiota/groups/devs-pelo-leokz/) e no 7Masters do Grupo iMasters. Sobre pérolas de programação tosca que encontramos em projetos de verdade mesmo! Aprenda o que NÃO se deve fazer nunca!
Transducers are a type of reducing function that take in a reducing function and give back another reducing function. They allow you to compose functions together in a chain or pipeline structure to quickly, easily and efficiently transform data. In PHP, we have the mtdowling/transducers library, built off the basis of the idea of Clojure's transducer library.
This session will introduce you to the new Form component in Symfony2. With the new domain-driven paradigma and its flexible design, the component opens a door to a wide range of possibilities. The brand new architecture makes creating complex forms easier and faster than ever before. This talk will teach you today what you need to know to build powerful forms tomorrow.
Everything you always wanted to know about forms* *but were afraid to askAndrea Giuliano
La componente dei Form di Symfony2 rende possibile la costruzione di diverse tipologie di form in modo del tutto semplice. La sua architettura flessibile e altamente scalabile permette di poter gestire strutture adatte ad ogni tipo di esigenza. Tuttavia, conoscere come utilizzare appieno tutta la sua potenza non è banale. In questo talk verrà trattato in profondità la componente Form di Symfony2, mostrando i suoi meccanismi di base e come utilizzarli per estenderli ed introdurre la propria logica di business, così da costruire form cuciti a misura delle tue necessità.
Models and Service Layers, Hemoglobin and HobgoblinsRoss Tuck
As presented at ZendCon 2014, AmsterdamPHP, PHPBenelux 2014, Sweetlake PHP and PHP Northwest 2013, an overview of some different patterns for integrating and managing logic throughout your application.
Deze presentatie is gegeven tijdens de KScope conferentie 2012
Spreker: Luc Bors
Titel: How to Bring Common UI Patterns to ADF
Onderwerp: Fusion Middleware - Subonderwerp: ADF
Eindgebruikers van bedrijfsapplicaties eisen dezelfde gebruikerservaring die ze kennen van bijvoorbeeld office applicaties en applicaties op het internet. Functies zoals bookmarking, favorieten en het werken met tabs wordt graag gezien in de dagelijkse werk. Het zoekmechanisme van Google, dat suggesties toont op basis van de ingevoerde tekst, is zo ´gewoon´ dat mensen dit in elke applicatie terug willen zien. Twitter en Facebook geven automatisch aan dat je nieuwe berichten hebt zonder dat je daar zelf eerst om moet vragen, dat gebruikers de normaalste zaak van de wereld vinden. Er zijn nog veel meer van deze UI patterns. In deze sessie leer je hoe een aantal van deze UI patterns in je ADF applicatie kunt inbouwen waardoor de eindgebruiker beschikking krijgt over bekende en vanzelfsprekende features. Dit zal leiden tot een snellere acceptatie van de applicatie en prettigere gebruikerservaring.
https://speakerdeck.com/willroth/50-laravel-tricks-in-50-minutes - origin
Laravel 5.1 raised the bar for framework documentation, but there's much, much more lurking beneath the surface. In this 50-minute session, we'll explore 50 (yes, 50!) high-leverage implementation tips & tricks that you just won't find in the docs: the IoC Container, Blade, Eloquent, Middleware, Routing, Commands, Queues, Events, Caching — we'll cover them all! Join us as we drink from the fire hose & learn to take advantage of everything that Laravel has to offer to build better software faster!
Type safe embedded domain-specific languagesArthur Xavier
Language is everything; it governs our lives: from our thought processes, our communication abilities and our understanding of the world, all the way up to law, politics, logic and programming. All of these domains of human experience are governed by different languages that talk to each other, and so should be your code. Haskell provides all the means necessary—and many more—to easily and safely use embedded small languages that are tailored to specific needs and business domains.
In this series of lectures and workshops, we will explore the whats, whys and hows of embedded domain-specific languages in Haskell, and how language oriented programing can bring type-safety, composability and simplicity to the development of complex applications.
Adding Dependency Injection to Legacy ApplicationsSam Hennessy
Dependency Injection (DI) is a fantastic technique, but what if you what to use dependency injection in your legacy application. Fear not! As someone who as done this very thing, I will show how you can successful and incrementally add DI to any application. I will present a number of recipes and solutions to common problems and give a tour of the various PHP DI projects and how they can help.
Devs for Leokz e 7Masters - WTF Oriented ProgrammingFabio Akita
Apresentação que fiz tanto no evento online beneficente Devs for Leokz (https://www.eventials.com/eduardo.shiota/groups/devs-pelo-leokz/) e no 7Masters do Grupo iMasters. Sobre pérolas de programação tosca que encontramos em projetos de verdade mesmo! Aprenda o que NÃO se deve fazer nunca!
Transducers are a type of reducing function that take in a reducing function and give back another reducing function. They allow you to compose functions together in a chain or pipeline structure to quickly, easily and efficiently transform data. In PHP, we have the mtdowling/transducers library, built off the basis of the idea of Clojure's transducer library.
This session will introduce you to the new Form component in Symfony2. With the new domain-driven paradigma and its flexible design, the component opens a door to a wide range of possibilities. The brand new architecture makes creating complex forms easier and faster than ever before. This talk will teach you today what you need to know to build powerful forms tomorrow.
Everything you always wanted to know about forms* *but were afraid to askAndrea Giuliano
La componente dei Form di Symfony2 rende possibile la costruzione di diverse tipologie di form in modo del tutto semplice. La sua architettura flessibile e altamente scalabile permette di poter gestire strutture adatte ad ogni tipo di esigenza. Tuttavia, conoscere come utilizzare appieno tutta la sua potenza non è banale. In questo talk verrà trattato in profondità la componente Form di Symfony2, mostrando i suoi meccanismi di base e come utilizzarli per estenderli ed introdurre la propria logica di business, così da costruire form cuciti a misura delle tue necessità.
Models and Service Layers, Hemoglobin and HobgoblinsRoss Tuck
As presented at ZendCon 2014, AmsterdamPHP, PHPBenelux 2014, Sweetlake PHP and PHP Northwest 2013, an overview of some different patterns for integrating and managing logic throughout your application.
Deze presentatie is gegeven tijdens de KScope conferentie 2012
Spreker: Luc Bors
Titel: How to Bring Common UI Patterns to ADF
Onderwerp: Fusion Middleware - Subonderwerp: ADF
Eindgebruikers van bedrijfsapplicaties eisen dezelfde gebruikerservaring die ze kennen van bijvoorbeeld office applicaties en applicaties op het internet. Functies zoals bookmarking, favorieten en het werken met tabs wordt graag gezien in de dagelijkse werk. Het zoekmechanisme van Google, dat suggesties toont op basis van de ingevoerde tekst, is zo ´gewoon´ dat mensen dit in elke applicatie terug willen zien. Twitter en Facebook geven automatisch aan dat je nieuwe berichten hebt zonder dat je daar zelf eerst om moet vragen, dat gebruikers de normaalste zaak van de wereld vinden. Er zijn nog veel meer van deze UI patterns. In deze sessie leer je hoe een aantal van deze UI patterns in je ADF applicatie kunt inbouwen waardoor de eindgebruiker beschikking krijgt over bekende en vanzelfsprekende features. Dit zal leiden tot een snellere acceptatie van de applicatie en prettigere gebruikerservaring.
https://speakerdeck.com/willroth/50-laravel-tricks-in-50-minutes - origin
Laravel 5.1 raised the bar for framework documentation, but there's much, much more lurking beneath the surface. In this 50-minute session, we'll explore 50 (yes, 50!) high-leverage implementation tips & tricks that you just won't find in the docs: the IoC Container, Blade, Eloquent, Middleware, Routing, Commands, Queues, Events, Caching — we'll cover them all! Join us as we drink from the fire hose & learn to take advantage of everything that Laravel has to offer to build better software faster!
Writing readable code is one of the most important aspects of web development. A developer should write code which another human is able to understand without the help of too many comments.
This talk will show you how to tidy up your code and write readable PHP.
Project link and video: https://github.com/nafizmd09/Student-Result-Management-System-with-PHP--Nafiz
Student Result Management System project with MySQL server.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Name: Nafiz Md Imtiaz Uddin
B.Sc. student of Computer Science & Technology (江西理工大学) [2019-2023]
personal Email: nafizmdimtiazuddin@yahoo.com
Academic Email: 2520190011@mail.jxust.edu.cn
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Silex is a brand new PHP 5.3 micro framework built on top of the Symfony2 de decoupled components. In this session, we will discover how to build and deploy powerful REST web services with such a micro framework and its embedded tools.
The first part of this talk will introduce the basics of the REST architecture. We fill focus on the main concepts of REST like HTTP methods, URIs and open formats like XML and JSON.
Then, we will discover how to deploy REST services using most of interesting Silex tools like database abstraction layer, template engine and input validation. We will also look at unit and functional testing frameworks with PHPUnit and HTTP caching with Edge Side Includes and Varnish support to improve performances.
Come to this talk prepared to learn about the Doctrine PHP open source project. The Doctrine project has been around for over a decade and has evolved from database abstraction software that dates back to the PEAR days. The packages provided by the Doctrine project have been downloaded almost 500 million times from packagist. In this talk we will take you through how to get started with Doctrine and how to take advantage of some of the more advanced features.
Talk I gave at Maceió DEV Meetup #6. Not only about Command Bus/Command Interface or whatever you name it, but a compilation of cool articles I found only that may help with understanding this architecture.
Building Persona: federated and privacy-sensitive identity for the Web (Open ...Francois Marier
This talk explores the challenges of the existing Web identity solutions and introduce the choices that were made during the development of Persona (formerly BrowserID), a new Open Source federated identity solution from Mozilla, designed and built to respect user privacy.
We, as developers, often think that we don’t have to or don’t need to know what are what they call design patterns. We think that we already know how to build a software and don’t need all this theory. Years after years, by having to deal with the low maintainability of my own codebases, I explored a lot of ways of decoupling applications, in order to have enterprise-grade software that last for years. With concrete examples, I want to share with you some design patterns and how they can help you to grow well structured and decoupled applications.
Do you TDD or BDD? Why not both? Come learn the "Double Loop" workflow and discover how you can use both Behavior Driven Development and Test Driven Development to write well designed, tested and documented code. Double Loop works for lone engineers, small teams or entire product departments. I'll cover the steps you'll take in the workflow in detail with best practices for behavior testing, integration testing and unit testing.
Do you TDD or BDD? Why not both? Come learn the "Double Loop" workflow and discover how you can use both Behavior Driven Development and Test Driven Development to write well designed, tested and documented code. Double Loop works for lone engineers, small teams or entire product departments. I'll cover the steps you'll take in the workflow as each role as well as tools for executing Double Loop
Do you TDD or BDD? Why not both? Come learn the "Double Loop" workflow and discover how you can use both Behavior Driven Development and Test Driven Development to write well designed, tested and documented code. Double Loop works for lone engineers, small teams or entire product departments. I'll cover the steps you'll take in the workflow as each role as well as tools for executing Double Loop
Join me for a retrospective look at how my team rewrote the core of a legacy application over six months and launched a well tested, stable product. In this session you'll learn how to work with an existing codebase without creating your own "legacy" code, by applying practices and tools such as identifying and using third party libraries, version control and code review, code quality measurements, BDD/TDD, and Continuous Integration.
This talk is about how my company took a broken e-commerce and LMS site written in an older style MVC framework and re-wrote a significant portion of it in Symfony and related tools (Doctrine, FOS Bundles, Sonata) over 6 months and created a stable, well-tested application.
An in-depth look at intermediate to advanced level Behat topics. We'll cover writing better features, regular expressions in steps, Context files, changes from Behat 2 to 3, and more,
Essentials of Automations: Optimizing FME Workflows with ParametersSafe Software
Are you looking to streamline your workflows and boost your projects’ efficiency? Do you find yourself searching for ways to add flexibility and control over your FME workflows? If so, you’re in the right place.
Join us for an insightful dive into the world of FME parameters, a critical element in optimizing workflow efficiency. This webinar marks the beginning of our three-part “Essentials of Automation” series. This first webinar is designed to equip you with the knowledge and skills to utilize parameters effectively: enhancing the flexibility, maintainability, and user control of your FME projects.
Here’s what you’ll gain:
- Essentials of FME Parameters: Understand the pivotal role of parameters, including Reader/Writer, Transformer, User, and FME Flow categories. Discover how they are the key to unlocking automation and optimization within your workflows.
- Practical Applications in FME Form: Delve into key user parameter types including choice, connections, and file URLs. Allow users to control how a workflow runs, making your workflows more reusable. Learn to import values and deliver the best user experience for your workflows while enhancing accuracy.
- Optimization Strategies in FME Flow: Explore the creation and strategic deployment of parameters in FME Flow, including the use of deployment and geometry parameters, to maximize workflow efficiency.
- Pro Tips for Success: Gain insights on parameterizing connections and leveraging new features like Conditional Visibility for clarity and simplicity.
We’ll wrap up with a glimpse into future webinars, followed by a Q&A session to address your specific questions surrounding this topic.
Don’t miss this opportunity to elevate your FME expertise and drive your projects to new heights of efficiency.
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...James Anderson
Effective Application Security in Software Delivery lifecycle using Deployment Firewall and DBOM
The modern software delivery process (or the CI/CD process) includes many tools, distributed teams, open-source code, and cloud platforms. Constant focus on speed to release software to market, along with the traditional slow and manual security checks has caused gaps in continuous security as an important piece in the software supply chain. Today organizations feel more susceptible to external and internal cyber threats due to the vast attack surface in their applications supply chain and the lack of end-to-end governance and risk management.
The software team must secure its software delivery process to avoid vulnerability and security breaches. This needs to be achieved with existing tool chains and without extensive rework of the delivery processes. This talk will present strategies and techniques for providing visibility into the true risk of the existing vulnerabilities, preventing the introduction of security issues in the software, resolving vulnerabilities in production environments quickly, and capturing the deployment bill of materials (DBOM).
Speakers:
Bob Boule
Robert Boule is a technology enthusiast with PASSION for technology and making things work along with a knack for helping others understand how things work. He comes with around 20 years of solution engineering experience in application security, software continuous delivery, and SaaS platforms. He is known for his dynamic presentations in CI/CD and application security integrated in software delivery lifecycle.
Gopinath Rebala
Gopinath Rebala is the CTO of OpsMx, where he has overall responsibility for the machine learning and data processing architectures for Secure Software Delivery. Gopi also has a strong connection with our customers, leading design and architecture for strategic implementations. Gopi is a frequent speaker and well-known leader in continuous delivery and integrating security into software delivery.
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Tobias Schneck
As AI technology is pushing into IT I was wondering myself, as an “infrastructure container kubernetes guy”, how get this fancy AI technology get managed from an infrastructure operational view? Is it possible to apply our lovely cloud native principals as well? What benefit’s both technologies could bring to each other?
Let me take this questions and provide you a short journey through existing deployment models and use cases for AI software. On practical examples, we discuss what cloud/on-premise strategy we may need for applying it to our own infrastructure to get it to work from an enterprise perspective. I want to give an overview about infrastructure requirements and technologies, what could be beneficial or limiting your AI use cases in an enterprise environment. An interactive Demo will give you some insides, what approaches I got already working for real.
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...UiPathCommunity
💥 Speed, accuracy, and scaling – discover the superpowers of GenAI in action with UiPath Document Understanding and Communications Mining™:
See how to accelerate model training and optimize model performance with active learning
Learn about the latest enhancements to out-of-the-box document processing – with little to no training required
Get an exclusive demo of the new family of UiPath LLMs – GenAI models specialized for processing different types of documents and messages
This is a hands-on session specifically designed for automation developers and AI enthusiasts seeking to enhance their knowledge in leveraging the latest intelligent document processing capabilities offered by UiPath.
Speakers:
👨🏫 Andras Palfi, Senior Product Manager, UiPath
👩🏫 Lenka Dulovicova, Product Program Manager, UiPath
Epistemic Interaction - tuning interfaces to provide information for AI supportAlan Dix
Paper presented at SYNERGY workshop at AVI 2024, Genoa, Italy. 3rd June 2024
https://alandix.com/academic/papers/synergy2024-epistemic/
As machine learning integrates deeper into human-computer interactions, the concept of epistemic interaction emerges, aiming to refine these interactions to enhance system adaptability. This approach encourages minor, intentional adjustments in user behaviour to enrich the data available for system learning. This paper introduces epistemic interaction within the context of human-system communication, illustrating how deliberate interaction design can improve system understanding and adaptation. Through concrete examples, we demonstrate the potential of epistemic interaction to significantly advance human-computer interaction by leveraging intuitive human communication strategies to inform system design and functionality, offering a novel pathway for enriching user-system engagements.
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualityInflectra
In this insightful webinar, Inflectra explores how artificial intelligence (AI) is transforming software development and testing. Discover how AI-powered tools are revolutionizing every stage of the software development lifecycle (SDLC), from design and prototyping to testing, deployment, and monitoring.
Learn about:
• The Future of Testing: How AI is shifting testing towards verification, analysis, and higher-level skills, while reducing repetitive tasks.
• Test Automation: How AI-powered test case generation, optimization, and self-healing tests are making testing more efficient and effective.
• Visual Testing: Explore the emerging capabilities of AI in visual testing and how it's set to revolutionize UI verification.
• Inflectra's AI Solutions: See demonstrations of Inflectra's cutting-edge AI tools like the ChatGPT plugin and Azure Open AI platform, designed to streamline your testing process.
Whether you're a developer, tester, or QA professional, this webinar will give you valuable insights into how AI is shaping the future of software delivery.
Neuro-symbolic is not enough, we need neuro-*semantic*Frank van Harmelen
Neuro-symbolic (NeSy) AI is on the rise. However, simply machine learning on just any symbolic structure is not sufficient to really harvest the gains of NeSy. These will only be gained when the symbolic structures have an actual semantics. I give an operational definition of semantics as “predictable inference”.
All of this illustrated with link prediction over knowledge graphs, but the argument is general.
Elevating Tactical DDD Patterns Through Object CalisthenicsDorra BARTAGUIZ
After immersing yourself in the blue book and its red counterpart, attending DDD-focused conferences, and applying tactical patterns, you're left with a crucial question: How do I ensure my design is effective? Tactical patterns within Domain-Driven Design (DDD) serve as guiding principles for creating clear and manageable domain models. However, achieving success with these patterns requires additional guidance. Interestingly, we've observed that a set of constraints initially designed for training purposes remarkably aligns with effective pattern implementation, offering a more ‘mechanical’ approach. Let's explore together how Object Calisthenics can elevate the design of your tactical DDD patterns, offering concrete help for those venturing into DDD for the first time!
The Art of the Pitch: WordPress Relationships and SalesLaura Byrne
Clients don’t know what they don’t know. What web solutions are right for them? How does WordPress come into the picture? How do you make sure you understand scope and timeline? What do you do if sometime changes?
All these questions and more will be explored as we talk about matching clients’ needs with what your agency offers without pulling teeth or pulling your hair out. Practical tips, and strategies for successful relationship building that leads to closing the deal.
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Albert Hoitingh
In this session I delve into the encryption technology used in Microsoft 365 and Microsoft Purview. Including the concepts of Customer Key and Double Key Encryption.
3. @jessicamauerhan | https://joind.in/talk/34870 | @PHPDet
What is SOLID?
● Five principles for Object
Oriented Programming
● Guidelines which can help
ensure system is easy to
maintain
● Primarily focused on
communication between
dependencies or
collaborators
4. Let ϕ( ) be a property provable
about objects of type T.
Then ϕ( ) should be true for
objects of type S where S is a
subtype of T
5. @jessicamauerhan | https://joind.in/talk/34870 | @PHPDet
Class Rectangle
{
protected $length;
protected $height;
public function area()
{
return $this->length * $this->area();
}
public function setLength($length)
{
$this->length = $length;
}
public function setHeight($height)
{
$this->height = $height;
}
}
Class Square extends Rectangle
{
public function setLength($length)
{
$this->length = $length;
$this->height = $length;
}
public function setHeight($height)
{
$this->length = $height;
$this->height = $height;
}
}
10. Class UserRegistration
{
public function register(Request $request): Response
{
//Collect user input
if (!$request->has('email') || !$request->has('password')) {
return new Response('register', ['error' => 'Please provide an email and a password']);
}
$user = new User();
$user->email = $request->get('email');
$user->password = $request->get('password');
}
}
11. Class UserRegistration
{
public function register(Request $request): Response
{
//Collect user input
if (!$request->has('email') || !$request->has('password')) {
return new Response('register', ['error' => 'Please provide an email and a password']);
}
$user = new User();
$user->email = $request->get('email');
$user->password = $request->get('password');
}
private function emailIsRegistered(string $email): bool
{
$dsn = 'host='.$_ENV['DB_HOST'].' dbname='.$_ENV['DB_DB'].' password='.$_ENV['DB_PASS'].' user='.$_ENV['DB_USER'];
$db = pg_connect($dsn);
$result = pg_query($db, "SELECT id FROM users WHERE (email='{$email}')");
$rows = pg_num_rows($result);
return $rows > 0;
}
}
12. Class UserRegistration
{
public function register(Request $request): Response
{
//Collect user input
if (!$request->has('email') || !$request->has('password')) {
return new Response('register', ['error' => 'Please provide an email and a password']);
}
$user = new User();
$user->email = $request->get('email');
$user->password = $request->get('password');
//Validate user input
if ($this->emailIsRegistered($user->getEmail())) {
return new Response('register', ['error' => 'Your email address is already registered']);
}
}
private function emailIsRegistered(string $email): bool
{
$dsn = 'host='.$_ENV['DB_HOST'].' dbname='.$_ENV['DB_DB'].' password='.$_ENV['DB_PASS'].' user='.$_ENV['DB_USER'];
$db = pg_connect($dsn);
$result = pg_query($db, "SELECT id FROM users WHERE (email='{$email}')");
$rows = pg_num_rows($result);
return $rows > 0;
}
}
13. Class UserRegistration
{
public function register(Request $request): Response
{
//Collect user input
if (!$request->has('email') || !$request->has('password')) {
return new Response('register', ['error' => 'Please provide an email and a password']);
}
$user = new User();
$user->email = $request->get('email');
$user->password = $request->get('password');
//Validate user input
if ($this->emailIsRegistered($user->getEmail())) {
return new Response('register', ['error' => 'Your email address is already registered']);
}
//Persist User
$this->saveUser($user);
}
private function emailIsRegistered(string $email): bool { [...] }
private function saveUser(User $user)
{
$dsn = 'host='.$_ENV['DB_HOST'].' dbname='.$_ENV['DB_DB'].' password='.$_ENV['DB_PASS'].' user='.$_ENV['DB_USER'];
$db = pg_connect($dsn);
pg_query($db, "INSERT INTO users(email, password) VALUES('{$user->email}', '{$user->password}')");
}
}
14. Class UserRegistration
{
public function register(Request $request): Response
{
[...]
}
private function emailIsRegistered(string $email): bool
{
$dsn = 'host='.$_ENV['DB_HOST'].' dbname='.$_ENV['DB_DB'].' password='.$_ENV['DB_PASS'].' user='.$_ENV['DB_USER'];
$db = pg_connect($dsn);
$result = pg_query($db, "SELECT id FROM users WHERE (email='{$email}')");
$rows = pg_num_rows($result);
return $rows > 0;
}
private function saveUser(User $user)
{
$dsn = 'host='.$_ENV['DB_HOST'].' dbname='.$_ENV['DB_DB'].' password='.$_ENV['DB_PASS'].' user='.$_ENV['DB_USER'];
$db = pg_connect($dsn);
pg_query($db, "INSERT INTO users(email, password) VALUES('{$user->email}', '{$user->password}')");
}
}
15. Class UserRegistration
{
public function register(Request $request): Response
{
[...]
}
private function emailIsRegistered(string $email): bool
{
$rows = DB::query("SELECT count(id) FROM users WHERE (email='{$email}')");
return $rows > 0;
}
private function saveUser(User $user)
{
DB::query("INSERT INTO users(email, password) VALUES('{$user->email}', '{$user->password}')");
}
}
16. Class UserRegistration
{
public function register(Request $request): Response
{
//Collect user input
if (!$request->has('email') || !$request->has('password')) {
return new Response('register', ['error' => 'Please provide an email and a password']);
}
$user = new User();
$user->email = $request->get('email');
$user->password = $request->get('password');
//Validate user input
if ($this->emailIsRegistered($user->getEmail())) {
return new Response('register', ['error' => 'Your email address is already registered']);
}
//Persist User
$this->saveUser($user);
//Send Confirmation Email
$this->sendConfirmationEmail($user->getEmail());
return new Response('register', ['success' => 'You are registered! Please check your email!']);
}
private function sendConfirmationEmail(string $email)
{
$subject = "Confirm Email";
$message = "Please <a>click here</a> to confirm your email!";
$headers = "From: mysite@email.com";
mail($email, $subject, $message, $headers);
}
17. Class UserRegistration
{
public function register(Request $request): Response {
//Collect user input
if (!$request->has('email') || !$request->has('password')) {
return new Response('register', ['error' => 'Please provide an email and a password']);
}
$user = new User();
$user->email = $request->get('email');
$user->password = $request->get('password');
//Validate user input
if ($this->emailIsRegistered($user->getEmail())) {
return new Response('register', ['error' => 'Your email address is already registered']);
}
//Persist User
$this->saveUser($user);
//Send Confirmation Email
$this->sendConfirmationEmail($user->getEmail());
return new Response('register', ['success' => 'You are registered! Please check your email!']);
}
private function sendConfirmationEmail(string $email) {
$subject = "Confirm Email";
$message = "Please <a>click here</a> to confirm your email!";
$headers = "From: mysite@email.com";
mail($email, $subject, $message, $headers);
}
private function saveUser(User $user) {
DB::query("INSERT INTO users(email, password) VALUES('{$user->email}', '{$user->password}')");
}
private function emailIsRegistered(string $email): bool {
$rows = DB::query("SELECT count(id) FROM users WHERE (email='{$email}')");
return $rows > 0;
}
}
18. Class UserRegistration
{
public function register(Request $request): Response {
//Collect user input
if (!$request->has('email') || !$request->has('password')) {
return new Response('register', ['error' => 'Please provide an email and a password']);
}
$user = new User();
$user->email = $request->get('email');
$user->password = $request->get('password');
//Validate user input
if ($this->emailIsRegistered($user->getEmail())) {
return new Response('register', ['error' => 'Your email address is already registered']);
}
//Persist User
$this->saveUser($user);
//Send Confirmation Email
$this->sendConfirmationEmail($user->getEmail());
return new Response('register', ['success' => 'You are registered! Please check your email!']);
}
private function sendConfirmationEmail(string $email) {
$subject = "Confirm Email";
$message = "Please <a>click here</a> to confirm your email!";
$headers = "From: mysite@email.com";
mail($email, $subject, $message, $headers);
}
private function saveUser(User $user) {
DB::query("INSERT INTO users(email, password) VALUES('{$user->email}', '{$user->password}')");
}
private function emailIsRegistered(string $email): bool {
$rows = DB::query("SELECT count(id) FROM users WHERE (email='{$email}')");
return $rows > 0;
}
}
19. @jessicamauerhan | https://joind.in/talk/34870 | @PHPDet
Dependency Injection
● Collaborators are supplied to
class from outside - aka
"injected" into it
Service Location
● Collaborators are retrieved or
instantiated from inside the
class using them
20. Class UserRegistration
{
public function register(Request $request): Response { [...] }
private function sendConfirmationEmail(string $email) { [...] }
private function saveUser(User $user)
{
$sql = "INSERT INTO users(email, password) VALUES('{$user->email}', '{$user->password}')"
DB::query($sql);
}
private function emailIsRegistered(string $email): bool
{
$rows = DB::query("SELECT count(id) FROM users WHERE (email='{$email}')");
return $rows > 0;
}
}
21. Class UserRegistration
{
private $db;
public function __construct(Database $db)
{
$this->db = $db;
}
public function register(Request $request): Response { [...] }
private function sendConfirmationEmail(string $email) { [...] }
private function saveUser(User $user)
{
$sql = "INSERT INTO users(email, password) VALUES('{$user->email}', '{$user->password}')"
$this->db->query($sql);
}
private function emailIsRegistered(string $email): bool
{
$rows = $this->db->query("SELECT count(id) FROM users WHERE (email='{$email}')");
return $rows > 0;
}
}
22. Class UserRegistration
{
private $db;
private $mailer;
public function __construct(Database $db, Mailer $mailer)
{
$this->db = $db;
$this->mailer = $mailer;
}
public function register(Request $request): Response { [...] }
private function sendConfirmationEmail(string $email)
{
//Convert our email to Mandrill's email
$mandrillEmail = [
'to' => ['email' => $email->getTo()],
'from_email' => $email->getFrom(),
'subject' => $email->getSubject(),
'text' => $email->getMessage()
];
$this->mandrill->send($mandrillEmail);
}
private function saveUser(User $user) { [...] }
private function emailIsRegistered(string $email): bool { [...] }
59. Interface Item
{
public function getName(): string;
public function getPrice(): float;
public function getShippingWeight(): float;
public function getShippingCost(): float;
}
60. Interface Item
{
public function getName(): string;
public function getPrice(): float;
public function getShippingWeight(): float;
public function getShippingCost(): float;
}
class Cart
{
private $items;
private $total;
public function addItem(Item $item)
{
$this->items[] = $item;
}
public function calculateTotal()
{
$subtotal = 0;
$shippingTotal = 0;
foreach ($this->items AS $item) {
$subtotal += $item->getPrice();
$shippingTotal += $item->getShippingCost();
}
return $subtotal + $shippingTotal;
}
}
61. Interface Item
{
public function getName(): string;
public function getPrice(): float;
public function getShippingWeight(): float;
public function getShippingCost(): float;
public function getWorkerAssigned(): Worker;
public function assignWorker(Worker $worker);
public function getServiceScheduledDate(): DateTime;
public function getServiceCompletedDate(): DateTime;
public function isCompleted(): bool;
}
Class Cart { [...] }
Class ServiceManager
{
private $services;
public function addService(Item $item)
{
$this->services[] = $item;
}
public function getCompletedServices()
{
$completed = [];
foreach ($this->services AS $service) {
if ($service->isCompleted()) {
$completed[] = $service;
}
}
return $completed;
}
}
63. Interface Item
{
public function getName(): string;
public function getPrice(): float;
public function getShippingWeight(): float;
public function getShippingCost(): float;
public function getWorkerAssigned(): Worker;
public function assignWorker(Worker $worker);
public function getServiceScheduledDate(): DateTime;
public function getServiceCompletedDate(): DateTime;
public function isCompleted(): bool;
}
Interface Buyable
{
public function getName(): string;
public function getPrice(): float;
}
Interface Product
{
public function getShippingWeight(): float;
public function getShippingCost(): float;
}
Interface Service
{
public function getWorkerAssigned(): Worker;
public function assignWorker(Worker $worker);
public function getServiceScheduledDate(): DateTime;
public function getServiceCompletedDate(): DateTime;
public function isCompleted(): bool;
}
64. Interface Buyable
{
public function getName(): string;
public function getPrice(): float;
}
Interface Product
{
public function getShippingWeight(): float;
public function getShippingCost(): float;
}
Interface Service
{
public function getWorkerAssigned(): Worker;
public function assignWorker(Worker $worker);
public function getServiceScheduledDate(): DateTime;
public function getServiceCompletedDate(): DateTime;
public function isCompleted(): bool;
}
Class BuyableItem implements Buyable
{
protected $name, $price;
public function __construct(string $name,
float $price)
{
$this->name = $name;
$this->price = $price;
}
public function getName(): string
{
return $this->name;
}
public function getPrice(): float
{
return $this->price;
}
}
65. Interface Buyable
{
public function getName(): string;
public function getPrice(): float;
}
Interface Product
{
public function getShippingWeight(): float;
public function getShippingCost(): float;
}
Interface Service
{
public function getWorkerAssigned(): Worker;
public function assignWorker(Worker $worker);
public function getServiceScheduledDate(): DateTime;
public function getServiceCompletedDate(): DateTime;
public function isCompleted(): bool;
}
Class BuyableItem implements Buyable { [...] }
Class BuyableProduct extends BuyableItem implements
Product
{
protected $shippingCost, $shippingWeight;
public function __construct(string $name,
float $price,
float $shippingCost,
float $shippingWeight)
{
$this->shippingCost = $shippingCost;
$this->shippingWeight = $shippingWeight;
parent::__construct($name, $price);
}
public function getShippingCost(): float {
return $this->getShippingCost();
}
public function getShippingWeight(): float {
return $this->shippingWeight;
}
}
66. S.O.L.I.D.
● Single Responsibility - Registration Class delegating to Collaborators
● Open/Closed - Adding new Notifiers without always editing Listener
● Liskov Substitution - Ensured Discount subtypes could be used as Discount
● Interface Segregation - Items use Buyable, Product and Service interfaces
● Dependency Inversion - Registration Controller, Emailer, Shopping Cart,
Notification Factory - all use interfaces, not implementations
67. @jessicamauerhan | https://joind.in/talk/34870 | @PHPDet
SLD: Apply Often
& Preemptively
● Single Responsibility
● Liskov Substitution
● Dependency Inversion
OI: Apply As Needed
When Changes Occur
● Open/Closed
● Interface Segregation