SlideShare a Scribd company logo
MIN-MAXING
Software Costs
Konstantin K.
@everzet
TECHNICAL
DEBT
Without
frameworks
Simple
frameworks
Enterprise
frameworks
IS MESS
PART OF
A COURSE?

Recommended for you

Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST

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.

silexphpsymfony2
Models and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsModels and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and Hobgoblins

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.

phpnw13phpphpbnl14
Mocking Demystified
Mocking DemystifiedMocking Demystified
Mocking Demystified

Replacing dependents with doubles is a central part of testing that every developer has to master. This talk goes over the different types of doubles and explains their place in testing, how to implement them in a mainstream mocking framework, and which strategies or doubles to use in different message exchange scenarios between objects. After this talk you will have moved a step forward in your understanding of testing in the context of object oriented programming.

mocksphpdoubles
MIN-MAXING
SOFTWARE COSTS
SOFTWARE FORCES
• Creation - Introduction of a brand new feature
• Change - Business-driven modification of existing feature
• Ownership - Physical capability to change a feature
• Control - Capability to sustainably change a feature
SOFTWARE COSTS
1. Cost of Creation
2. Cost of Change
3. Cost of Control
COST OF CREATION

Recommended for you

Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns

This session introduces most well known design patterns to build PHP classes and objects that need to store and fetch data from a relational databases. The session will describe the difference between of the Active Record, the Table and Row Data Gateway and the Data Mapper pattern. We will also examine some technical advantages and drawbacks of these implementations. This talk will expose some of the best PHP tools, which ease database interactions and are built on top of these patterns.

dataphpmapper
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful software

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.

separation of concernshexagonal architecture
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence

This document summarizes the history of PHP persistence from 1995 to present day. It begins with early file handling in PHP/FI in 1995 and the introduction of database support. It then discusses the evolution of code reusability through functions and classes. Professional abstraction layers like PEAR and later ORM frameworks provided more robust and standardized APIs. NoSQL databases and drivers were later incorporated, moving beyond relational databases. Current frameworks provide object document mapping for non-SQL databases like MongoDB.

propelphpmysql
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation
CONVENTIONS
OPTIMISE
FOR CREATION
$ bin/rails generate controller welcome index
from django.contrib import admin
from . import models
admin.site.register(models.Article)

Recommended for you

Rich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationRich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 Application

Presentation for Symfony Camp UA 2012. * What are Rich Model, Service Layer & Layered Architecture * Layered architecture in Sf2 Application * Integration with 3rd party bundles

symfony2symfonymodel
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolve

Why async and functional programming in PHP7 suck and how to get over it? www.xsolve.pl/nobodyexpects

immutabilityphpconplphpslang
Command Bus To Awesome Town
Command Bus To Awesome TownCommand Bus To Awesome Town
Command Bus To Awesome Town

As presented at Dutch PHP Conference 2015, an introduction to command buses, how to implement your own in PHP and why they're both useful but unimportant.

phpcommand busservice layers
package hello;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GreetingController {
...
}
CREATION
IS LIMITED BY
THE LIFE SPAN
Creation
→
Change
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation
Creation
→
Change
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation
Pure observation &
personal experience

Recommended for you

Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web services

This document discusses building web services using the Zend Framework. It introduces key components for building SOAP, XML-RPC, and RESTful services, including the Zend_Soap, Zend_XmlRpc, and Zend_Rest libraries. It provides an example of building a timesheet API and exposing it through different protocols, demonstrating how to define methods, handle requests and responses, and implement clients. Documentation of the API using docblocks is also covered.

macqelsoaprest
Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!

Slides from my talk at Dutch PHP Conference in Amsterdam More Domain-Driven Design related content at: https://domaincentric.net/

phpvarnishdesign
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersPHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4Developers

Slides from my talk at 4Developers conference in Warsaw More Domain-Driven Design related content at: https://domaincentric.net/

phpdesingtesting
Creation
→
Change
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation
Conventional Project
Creation
→
Change
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation
Conventional Project
Conventional Project
Convention-based projects either
die a hero or live long enough to
see themselves become the villain.
COST OF CHANGE

Recommended for you

CQRS and Event Sourcing in a Symfony application
CQRS and Event Sourcing in a Symfony applicationCQRS and Event Sourcing in a Symfony application
CQRS and Event Sourcing in a Symfony application

The document discusses using CQRS and event sourcing in a Symfony application. It covers building the domain model to use events, storing events in a repository, using a message bus for commands and events, and creating projections from events for querying. Event handlers can trigger new commands, and projections rebuild data from events for fast reads. The approach allows an application to handle commands asynchronously through decoupled services while maintaining an immutable record of events for audit purposes.

event sourcingsymfonyevents
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in action

The document contains code for unit testing a PHP MVC application using PHPUnit. It includes: - Code for the Todo model and its tests using PHPUnit assertions. - Configuration for PHPUnit to run tests for the application and library. - Tests for the IndexController using a Test_ControllerTestCase class with helper methods. - Code for Request, Response and View classes to mock the MVC framework. - A test to interact with the application interface using Selenium. The document shows the project structure for an MVC application and library with tests. It demonstrates how to test models, controllers and the user interface using test doubles, assertions and helper methods in PHPUnit.

phpunit
Forget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowForget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers Cracow

Slides from my talk at PHPers meet-up in Cracow More Domain-Driven Design related content at: https://domaincentric.net/

foundationcracowvarnish
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation Cost of Change
THE SEARCH
FUNCTION
public function searchAction(Request $req)
{
$form = $this->createForm(new SearchQueryType, new SearchQuery);
$normalizedOrderBys = $this->getNormalizedOrderBys($filteredOrderBys);
$this->computeSearchQuery($req, $filteredOrderBys);
if ($req->query->has('search_query')) {
/** @var $solarium Solarium_Client */
$solarium = $this->get('solarium.client');
$select = $solarium->createSelect();
// configure dismax
$dismax = $select->getDisMax();
$dismax->setQueryFields(array('name^4', 'description', 'tags', 'text', 'text_ngram', 'name_split^2'));
if ($req->query->has('search_query')) {
$form->bind($req);
if ($form->isValid()) {
$escapedQuery = $select->getHelper()->escapeTerm($form->getData()->getQuery());
$escapedQuery = preg_replace('/(^| )-(S)/', '$1-$2', $escapedQuery);
$escapedQuery = preg_replace('/(^| )+(S)/', '$1+$2', $escapedQuery);
if ((substr_count($escapedQuery, '"') % 2) == 0) {
$escapedQuery = str_replace('"', '"', $escapedQuery);
}
$select->setQuery($escapedQuery);
}
}
} elseif ($req->getRequestFormat() === 'json') {
return JsonResponse::create(array(
'error' => 'Missing search query, example: ?q=example'
), 400)->setCallback($req->query->get('callback'));
}
return $this->render('SomeAppWebBundle:Web:search.html.twig');
}
public function searchAction(Request $req)
{
$form = $this->createForm(new SearchQueryType, new SearchQuery);
$normalizedOrderBys = $this->getNormalizedOrderBys($filteredOrderBys);
$this->computeSearchQuery($req, $filteredOrderBys);
if ($req->query->has('search_query')) {
/** @var $solarium Solarium_Client */
$solarium = $this->get('solarium.client');
$select = $solarium->createSelect();
// configure dismax
$dismax = $select->getDisMax();
$dismax->setQueryFields(array('name^4', 'description', 'tags', 'text', 'text_ngram', 'name_split^2'));
if ($req->query->has('search_query')) {
$form->bind($req);
if ($form->isValid()) {
$escapedQuery = $select->getHelper()->escapeTerm($form->getData()->getQuery());
$escapedQuery = preg_replace('/(^| )-(S)/', '$1-$2', $escapedQuery);
$escapedQuery = preg_replace('/(^| )+(S)/', '$1+$2', $escapedQuery);
if ((substr_count($escapedQuery, '"') % 2) == 0) {
$escapedQuery = str_replace('"', '"', $escapedQuery);
}
$select->setQuery($escapedQuery);
}
}
} elseif ($req->getRequestFormat() === 'json') {
return JsonResponse::create(array(
'error' => 'Missing search query, example: ?q=example'
), 400)->setCallback($req->query->get('callback'));
}
return $this->render('SomeAppWebBundle:Web:search.html.twig');
}

Recommended for you

Adding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy ApplicationsAdding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy Applications

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.

iocduck typing
November Camp - Spec BDD with PHPSpec 2
November Camp - Spec BDD with PHPSpec 2November Camp - Spec BDD with PHPSpec 2
November Camp - Spec BDD with PHPSpec 2

My slides on PHPSpec 2 from Symfony November Camp Stockholm. www.symfony.se/november-camp/ More Domain-Driven Design related content at: https://domaincentric.net/

novembercampsweden
Moving away from legacy code with BDD
Moving away from legacy code with BDDMoving away from legacy code with BDD
Moving away from legacy code with BDD

This document discusses strategies for moving away from legacy code using behavior-driven development (BDD). It summarizes three popular options: 1) Rewriting the entire application from scratch using best practices, 2) Doing technical refactoring of the code, and 3) Taking a business-focused approach using the "BDD pipeline" which involves impact mapping, prioritizing features, example workshops, and BDD layers to support planned changes. The presenter argues that the third option of a BDD pipeline is preferable to a full rewrite or only technical refactoring as it focuses on delivering business value over time rather than rewriting the code.

agilebddbrownfield
HOW LONG WOULD
IT TAKETO ADD TAGS
SUPPORT?
public function searchAction(Request $req)
{
$form = $this->createForm(new SearchQueryType, new SearchQuery);
$normalizedOrderBys = $this->getNormalizedOrderBys($filteredOrderBys);
$this->computeSearchQuery($req, $filteredOrderBys);
if ($req->query->has('search_query')) {
/** @var $solarium Solarium_Client */
$solarium = $this->get('solarium.client');
$select = $solarium->createSelect();
// configure dismax
$dismax = $select->getDisMax();
$dismax->setQueryFields(array('name^4', 'description', 'tags', 'text', 'text_ngram', 'name_split^2'));
if ($req->query->has('search_query')) {
$form->bind($req);
if ($form->isValid()) {
$escapedQuery = $select->getHelper()->escapeTerm($form->getData()->getQuery());
$escapedQuery = preg_replace('/(^| )-(S)/', '$1-$2', $escapedQuery);
$escapedQuery = preg_replace('/(^| )+(S)/', '$1+$2', $escapedQuery);
if ((substr_count($escapedQuery, '"') % 2) == 0) {
$escapedQuery = str_replace('"', '"', $escapedQuery);
}
$select->setQuery($escapedQuery);
}
}
} elseif ($req->getRequestFormat() === 'json') {
return JsonResponse::create(array(
'error' => 'Missing search query, example: ?q=example'
), 400)->setCallback($req->query->get('callback'));
}
return $this->render('SomeAppWebBundle:Web:search.html.twig');
}
public function searchAction(Request $req)
{
$form = $this->createForm(new SearchQueryType, new SearchQuery);
$this->computeSearchQuery($req, $filteredOrderBys);
$typeFilter = $req->query->get('type');
if ($req->query->has('search_query') || $typeFilter) {
/** @var $solarium Solarium_Client */
$solarium = $this->get('solarium.client');
$select = $solarium->createSelect();
// configure dismax
$dismax = $select->getDisMax();
$dismax->setQueryFields(array('name^4', 'description', 'tags', 'text', 'text_ngram', 'name_split^2'));
$dismax->setPhraseFields(array('description'));
$dismax->setBoostFunctions(array('log(trendiness)^10'));
$dismax->setMinimumMatch(1);
$dismax->setQueryParser('edismax');
// filter by type
if ($typeFilter) {
$filterQueryTerm = sprintf('type:"%s"', $select->getHelper()->escapeTerm($typeFilter));
$filterQuery = $select->createFilterQuery('type')->setQuery($filterQueryTerm);
$select->addFilterQuery($filterQuery);
}
if ($req->query->has('search_query')) {
$form->bind($req);
if ($form->isValid()) {
$escapedQuery = $select->getHelper()->escapeTerm($form->getData()->getQuery());
$escapedQuery = preg_replace('/(^| )-(S)/', '$1-$2', $escapedQuery);
$escapedQuery = preg_replace('/(^| )+(S)/', '$1+$2', $escapedQuery);
if ((substr_count($escapedQuery, '"') % 2) == 0) {
$escapedQuery = str_replace('"', '"', $escapedQuery);
}
$select->setQuery($escapedQuery);
}
}
$paginator = new Pagerfanta(new SolariumAdapter($solarium, $select));
$perPage = $req->query->getInt('per_page', 15);
if ($perPage <= 0 || $perPage > 100) {
if ($req->getRequestFormat() === 'json') {
return JsonResponse::create(array(
'status' => 'error',
'message' => 'The optional packages per_page parameter must be an integer between 1 and 100 (default: 15)',
), 400)->setCallback($req->query->get('callback'));
}
$perPage = max(0, min(100, $perPage));
}
} elseif ($req->getRequestFormat() === 'json') {
return JsonResponse::create(array(
'error' => 'Missing search query, example: ?q=example'
), 400)->setCallback($req->query->get('callback'));
}
return $this->render('SomeAppWebBundle:Web:search.html.twig');
}
{
$form = $this->createForm(new SearchQueryType, new SearchQuery);
$filteredOrderBys = $this->getFilteredOrderedBys($req);
$normalizedOrderBys = $this->getNormalizedOrderBys($filteredOrderBys);
$this->computeSearchQuery($req, $filteredOrderBys);
$typeFilter = $req->query->get('type');
$tagsFilter = $req->query->get('tags');
if ($req->query->has('search_query') || $typeFilter || $tagsFilter) {
/** @var $solarium Solarium_Client */
$solarium = $this->get('solarium.client');
$select = $solarium->createSelect();
// configure dismax
$dismax = $select->getDisMax();
$dismax->setQueryFields(array('name^4', 'description', 'tags', 'text', 'text_ngram', 'name_split^2'));
$dismax->setPhraseFields(array('description'));
$dismax->setBoostFunctions(array('log(trendiness)^10'));
$dismax->setMinimumMatch(1);
$dismax->setQueryParser('edismax');
// filter by type
if ($typeFilter) {
$filterQueryTerm = sprintf('type:"%s"', $select->getHelper()->escapeTerm($typeFilter));
$filterQuery = $select->createFilterQuery('type')->setQuery($filterQueryTerm);
$select->addFilterQuery($filterQuery);
}
// filter by tags
if ($tagsFilter) {
$tags = array();
foreach ((array) $tagsFilter as $tag) {
$tags[] = $select->getHelper()->escapeTerm($tag);
}
$filterQueryTerm = sprintf('tags:("%s")', implode('" AND "', $tags));
$filterQuery = $select->createFilterQuery('tags')->setQuery($filterQueryTerm);
$select->addFilterQuery($filterQuery);
}
if (!empty($filteredOrderBys)) {
$select->addSorts($normalizedOrderBys);
}
if ($req->query->has('search_query')) {
$form->bind($req);
if ($form->isValid()) {
$escapedQuery = $select->getHelper()->escapeTerm($form->getData()->getQuery());
$escapedQuery = preg_replace('/(^| )-(S)/', '$1-$2', $escapedQuery);
$escapedQuery = preg_replace('/(^| )+(S)/', '$1+$2', $escapedQuery);
if ((substr_count($escapedQuery, '"') % 2) == 0) {
$escapedQuery = str_replace('"', '"', $escapedQuery);
}
$select->setQuery($escapedQuery);
}
}
$paginator = new Pagerfanta(new SolariumAdapter($solarium, $select));
$perPage = $req->query->getInt('per_page', 15);
if ($perPage <= 0 || $perPage > 100) {
if ($req->getRequestFormat() === 'json') {
return JsonResponse::create(array(
'status' => 'error',
'message' => 'The optional packages per_page parameter must be an integer between 1 and 100 (default: 15)',
), 400)->setCallback($req->query->get('callback'));
}
$perPage = max(0, min(100, $perPage));
}
$paginator->setMaxPerPage($perPage);
$paginator->setCurrentPage($req->query->get('page', 1), false, true);
$metadata = array();
foreach ($paginator as $package) {
if (is_numeric($package->id)) {
$metadata['downloads'][$package->id] = $package->downloads;
$metadata['favers'][$package->id] = $package->favers;
}
}
if ($req->getRequestFormat() === 'json') {
try {
$result = array(
'results' => array(),
'total' => $paginator->getNbResults(),
);
} catch (Solarium_Client_HttpException $e) {
return JsonResponse::create(array(
'status' => 'error',
'message' => 'Could not connect to the search server',
), 500)->setCallback($req->query->get('callback'));
}
return JsonResponse::create($result)->setCallback($req->query->get('callback'));
}
if ($req->isXmlHttpRequest()) {
try {
return $this->render('PackagistWebBundle:Web:search.html.twig', array(
'packages' => $paginator,
'meta' => $metadata,
'noLayout' => true,
));
} catch (Twig_Error_Runtime $e) {
if (!$e->getPrevious() instanceof Solarium_Client_HttpException) {
throw $e;
}
return JsonResponse::create(array(
'status' => 'error',
'message' => 'Could not connect to the search server',
), 500)->setCallback($req->query->get('callback'));
}
}
return $this->render('PackagistWebBundle:Web:search.html.twig', array(
'packages' => $paginator,
'meta' => $metadata,
));
} elseif ($req->getRequestFormat() === 'json') {
return JsonResponse::create(array(
'error' => 'Missing search query, example: ?q=example'
), 400)->setCallback($req->query->get('callback'));
}
return $this->render('PackagistWebBundle:Web:search.html.twig');

Recommended for you

Modern Agile Project Toolbox
Modern Agile Project ToolboxModern Agile Project Toolbox
Modern Agile Project Toolbox

Agile is defined by an open development process driven by collaboration. But we know that collaboration is not always easy, and we need to come up with creative ways of establishing and supporting it. For this reason, the agile community was very busy in the last decade coming up with new and innovative tools to boost collaboration - eg story mapping, impact mapping, example mapping, risk brainstorming, the 3 amigos workshop, stakeholder mapping, event storming etc. There are a lot of tools. But how do all they fit together, and when should you use one or another in the wider context of a project delivery? This is a very practical session that will attempt to group and present modern agile tools in the context of project delivery and provide guidance recommendations for their use.

example mappingagilegoals
Moving away from legacy code (AgileCymru)
Moving away from legacy code  (AgileCymru)Moving away from legacy code  (AgileCymru)
Moving away from legacy code (AgileCymru)

Greenfield projects are awesome – you can develop highest quality application using best practices on the market. But what if your bread actually is Legacy projects? Does it mean that you need to descend into darkness of QA absence? Does it mean that you can’t use Agile or modern communication practices like BDD? This talk will show you how to be successful even with the oldest legacy projects out there through the usage of Agile processes and tools like Impact Mapping, Feature Mapping, Example Workshop, Story and Spec BDDs.

legacyagileimpact mapping
Taking back BDD
Taking back BDDTaking back BDD
Taking back BDD

Behaviour Driven Development (BDD) and Domain Driven Design (DDD) seen a great growth in adoption in recent years. We are all creating new practices and tools that try and bring these two very important modern methodologies together. What if we have it backwards and they were actually together all along? What if most of the misunderstandings and challenges we face in implementing BDD are spawned from the very simple mistake of us separating something that was created as a whole? In this talk we'll delve into BDD as it was meant to be done from the beginning and look at its very rooted connection with the software design.

bdddddmodelling
{
$form = $this->createForm(new SearchQueryType, new SearchQuery);
$filteredOrderBys = $this->getFilteredOrderedBys($req);
$normalizedOrderBys = $this->getNormalizedOrderBys($filteredOrderBys);
$this->computeSearchQuery($req, $filteredOrderBys);
$typeFilter = $req->query->get('type');
$tagsFilter = $req->query->get('tags');
if ($req->query->has('search_query') || $typeFilter || $tagsFilter) {
/** @var $solarium Solarium_Client */
$solarium = $this->get('solarium.client');
$select = $solarium->createSelect();
// configure dismax
$dismax = $select->getDisMax();
$dismax->setQueryFields(array('name^4', 'description', 'tags', 'text', 'text_ngram', 'name_split^2'));
$dismax->setPhraseFields(array('description'));
$dismax->setBoostFunctions(array('log(trendiness)^10'));
$dismax->setMinimumMatch(1);
$dismax->setQueryParser('edismax');
// filter by type
if ($typeFilter) {
$filterQueryTerm = sprintf('type:"%s"', $select->getHelper()->escapeTerm($typeFilter));
$filterQuery = $select->createFilterQuery('type')->setQuery($filterQueryTerm);
$select->addFilterQuery($filterQuery);
}
// filter by tags
if ($tagsFilter) {
$tags = array();
foreach ((array) $tagsFilter as $tag) {
$tags[] = $select->getHelper()->escapeTerm($tag);
}
$filterQueryTerm = sprintf('tags:("%s")', implode('" AND "', $tags));
$filterQuery = $select->createFilterQuery('tags')->setQuery($filterQueryTerm);
$select->addFilterQuery($filterQuery);
}
if (!empty($filteredOrderBys)) {
$select->addSorts($normalizedOrderBys);
}
if ($req->query->has('search_query')) {
$form->bind($req);
if ($form->isValid()) {
$escapedQuery = $select->getHelper()->escapeTerm($form->getData()->getQuery());
$escapedQuery = preg_replace('/(^| )-(S)/', '$1-$2', $escapedQuery);
$escapedQuery = preg_replace('/(^| )+(S)/', '$1+$2', $escapedQuery);
if ((substr_count($escapedQuery, '"') % 2) == 0) {
$escapedQuery = str_replace('"', '"', $escapedQuery);
}
$select->setQuery($escapedQuery);
}
}
$paginator = new Pagerfanta(new SolariumAdapter($solarium, $select));
$perPage = $req->query->getInt('per_page', 15);
if ($perPage <= 0 || $perPage > 100) {
if ($req->getRequestFormat() === 'json') {
return JsonResponse::create(array(
'status' => 'error',
'message' => 'The optional packages per_page parameter must be an integer between 1 and 100 (default: 15)',
), 400)->setCallback($req->query->get('callback'));
}
$perPage = max(0, min(100, $perPage));
}
$paginator->setMaxPerPage($perPage);
$paginator->setCurrentPage($req->query->get('page', 1), false, true);
$metadata = array();
foreach ($paginator as $package) {
if (is_numeric($package->id)) {
$metadata['downloads'][$package->id] = $package->downloads;
$metadata['favers'][$package->id] = $package->favers;
}
}
if ($req->getRequestFormat() === 'json') {
try {
$result = array(
'results' => array(),
'total' => $paginator->getNbResults(),
);
} catch (Solarium_Client_HttpException $e) {
return JsonResponse::create(array(
'status' => 'error',
'message' => 'Could not connect to the search server',
), 500)->setCallback($req->query->get('callback'));
}
return JsonResponse::create($result)->setCallback($req->query->get('callback'));
}
if ($req->isXmlHttpRequest()) {
try {
return $this->render('PackagistWebBundle:Web:search.html.twig', array(
'packages' => $paginator,
'meta' => $metadata,
'noLayout' => true,
));
} catch (Twig_Error_Runtime $e) {
if (!$e->getPrevious() instanceof Solarium_Client_HttpException) {
throw $e;
}
return JsonResponse::create(array(
'status' => 'error',
'message' => 'Could not connect to the search server',
), 500)->setCallback($req->query->get('callback'));
}
}
return $this->render('PackagistWebBundle:Web:search.html.twig', array(
'packages' => $paginator,
'meta' => $metadata,
));
} elseif ($req->getRequestFormat() === 'json') {
return JsonResponse::create(array(
'error' => 'Missing search query, example: ?q=example'
), 400)->setCallback($req->query->get('callback'));
}
return $this->render('PackagistWebBundle:Web:search.html.twig');
{
$form = $this->createForm(new SearchQueryType, new SearchQuery);
$filteredOrderBys = $this->getFilteredOrderedBys($req);
$normalizedOrderBys = $this->getNormalizedOrderBys($filteredOrderBys);
$this->computeSearchQuery($req, $filteredOrderBys);
$typeFilter = $req->query->get('type');
$tagsFilter = $req->query->get('tags');
if ($req->query->has('search_query') || $typeFilter || $tagsFilter) {
/** @var $solarium Solarium_Client */
$solarium = $this->get('solarium.client');
$select = $solarium->createSelect();
// configure dismax
$dismax = $select->getDisMax();
$dismax->setQueryFields(array('name^4', 'description', 'tags', 'text', 'text_ngram', 'name_split^2'));
$dismax->setPhraseFields(array('description'));
$dismax->setBoostFunctions(array('log(trendiness)^10'));
$dismax->setMinimumMatch(1);
$dismax->setQueryParser('edismax');
// filter by type
if ($typeFilter) {
$filterQueryTerm = sprintf('type:"%s"', $select->getHelper()->escapeTerm($typeFilter));
$filterQuery = $select->createFilterQuery('type')->setQuery($filterQueryTerm);
$select->addFilterQuery($filterQuery);
}
// filter by tags
if ($tagsFilter) {
$tags = array();
foreach ((array) $tagsFilter as $tag) {
$tags[] = $select->getHelper()->escapeTerm($tag);
}
$filterQueryTerm = sprintf('tags:("%s")', implode('" AND "', $tags));
$filterQuery = $select->createFilterQuery('tags')->setQuery($filterQueryTerm);
$select->addFilterQuery($filterQuery);
}
if (!empty($filteredOrderBys)) {
$select->addSorts($normalizedOrderBys);
}
if ($req->query->has('search_query')) {
$form->bind($req);
if ($form->isValid()) {
$escapedQuery = $select->getHelper()->escapeTerm($form->getData()->getQuery());
$escapedQuery = preg_replace('/(^| )-(S)/', '$1-$2', $escapedQuery);
$escapedQuery = preg_replace('/(^| )+(S)/', '$1+$2', $escapedQuery);
if ((substr_count($escapedQuery, '"') % 2) == 0) {
$escapedQuery = str_replace('"', '"', $escapedQuery);
}
$select->setQuery($escapedQuery);
}
}
$paginator = new Pagerfanta(new SolariumAdapter($solarium, $select));
$perPage = $req->query->getInt('per_page', 15);
if ($perPage <= 0 || $perPage > 100) {
if ($req->getRequestFormat() === 'json') {
return JsonResponse::create(array(
'status' => 'error',
'message' => 'The optional packages per_page parameter must be an integer between 1 and 100 (default: 15)',
), 400)->setCallback($req->query->get('callback'));
}
$perPage = max(0, min(100, $perPage));
}
$paginator->setMaxPerPage($perPage);
$paginator->setCurrentPage($req->query->get('page', 1), false, true);
$metadata = array();
foreach ($paginator as $package) {
if (is_numeric($package->id)) {
$metadata['downloads'][$package->id] = $package->downloads;
$metadata['favers'][$package->id] = $package->favers;
}
}
if ($req->getRequestFormat() === 'json') {
try {
$result = array(
'results' => array(),
'total' => $paginator->getNbResults(),
);
} catch (Solarium_Client_HttpException $e) {
return JsonResponse::create(array(
'status' => 'error',
'message' => 'Could not connect to the search server',
), 500)->setCallback($req->query->get('callback'));
}
return JsonResponse::create($result)->setCallback($req->query->get('callback'));
}
if ($req->isXmlHttpRequest()) {
try {
return $this->render('PackagistWebBundle:Web:search.html.twig', array(
'packages' => $paginator,
'meta' => $metadata,
'noLayout' => true,
));
} catch (Twig_Error_Runtime $e) {
if (!$e->getPrevious() instanceof Solarium_Client_HttpException) {
throw $e;
}
return JsonResponse::create(array(
'status' => 'error',
'message' => 'Could not connect to the search server',
), 500)->setCallback($req->query->get('callback'));
}
}
return $this->render('PackagistWebBundle:Web:search.html.twig', array(
'packages' => $paginator,
'meta' => $metadata,
));
} elseif ($req->getRequestFormat() === 'json') {
return JsonResponse::create(array(
'error' => 'Missing search query, example: ?q=example'
), 400)->setCallback($req->query->get('callback'));
}
return $this->render('PackagistWebBundle:Web:search.html.twig');
CHANGE
KICKS IN AFTER
CREATION STOPS
Creation
→
Change
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation Cost of Change
Creation
→
Change
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation Cost of Change
Enterprise Project

Recommended for you

BDD by example
BDD by exampleBDD by example
BDD by example

BDD focuses on using scenarios to eliminate translation costs in conversations between business and technical teams. It uses scenarios to drive development and testing at multiple levels. DDD also aims to reduce translation costs, but focuses on eliminating them in code through the use of domain models. Both approaches help facilitate a shared ubiquitous language between business and technical teams to improve understanding and ensure the system meets business needs.

bddubiquitous languageddd
Enabling agile devliery through enabling BDD in PHP projects
Enabling agile devliery through enabling BDD in PHP projectsEnabling agile devliery through enabling BDD in PHP projects
Enabling agile devliery through enabling BDD in PHP projects

What is the purpose of BDD and how it fits into the Agile development? If you ever wondered what are the benefits of BDD or why should you care about tools like Behat or PhpSpec, this talk will try to guide you through the reasoning and goals of modern Agile practices and tools in PHP.

phpbddagile
Modern Project Toolbox
Modern Project ToolboxModern Project Toolbox
Modern Project Toolbox

Agile is defined by an open development process driven by collaboration. But you know that collaboration is not always an easy process and in a lot of cases you need to come up with creative ways of establishing and supporting it. By that reason Agile community was very busy in the last decade coming up with new and innovative tools to boost collaboration on different aspects of development and planning - Story Mapping, Impact Mapping, Example Mapping, Risk Brainstorming, Three Amigos workshop, Stakeholder Mapping, Event Storming, etc. There’s a lot of tools. But how do all they fit together and when should you use one or another in the wider context of a project delivery? This is a very practical talk that will attempt to group and present modern Agile tools in the context of project delivery and will provide guidance recommendations for their use.

workshopsleanmetrics
Creation
→
Change
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation Cost of Change
Enterprise Project
Enterprise Project
FORCE DYNAMICS
CONVENTION-BASED
FRAMEWORK
Min-Maxing Software Costs

Recommended for you

Being effective with legacy projects
Being effective with legacy projectsBeing effective with legacy projects
Being effective with legacy projects

Greenfield projects are bunch of fun – you can apply craziest cutting edge architecture decisions and use best practices on the market. But what if you stuck in a Legacy project? Does it mean that you need to descend into darkness of despair on every required change? Does it mean that you can’t effectively use Agile or any modern design practices or tools? This talk will show you how to be successful even with the oldest legacy projects out there through the focus on value and measurement. It will present couple of ways to approach software rewrites and maintain sanity when working with haphazardly put together code.

bdddeliberate discoverylegacy
BDD в PHP с Behat и Mink
BDD в PHP с Behat и MinkBDD в PHP с Behat и Mink
BDD в PHP с Behat и Mink

История и примеры использования BDD в PHP и ZF с помощью Behat и Mink.

zfbddphp
BDD для PHP проектов
BDD для PHP проектовBDD для PHP проектов
BDD для PHP проектов
bddphpbehat
Your first feature
Controlled Code
Controlled Code
Your second feature
Controlled Code
Controlled Code

Recommended for you

Bridging The Communication Gap, Fast
Bridging The Communication Gap, Fast Bridging The Communication Gap, Fast
Bridging The Communication Gap, Fast

The document discusses bridging communication gaps and the evolution of agile processes. It describes the speaker's journey into behavior driven development (BDD) and how agile processes have changed at their company, Inviqa. It emphasizes that discovering business needs, exploring options, and making commitments are important for software development. Building the right thing, building it right, and building for the right reasons are highlighted.

bddimpact mappingdeliberate discovery
Moving away from legacy code with BDD
Moving away from legacy code with BDDMoving away from legacy code with BDD
Moving away from legacy code with BDD

Greenfield projects are awesome – you can develop highest quality application using best practices on the market. But what if your bread actually is Legacy projects? Does it mean that you need to descend into darkness of QA absence? This talk will show you how to be successful even with the oldest legacy projects out there through the introduction of Agile processes and tools like Behat.

phpbddrefactoring
Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
 Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011 Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011

In the first part of the presentation we see how Symfony2 implements HTTP cache. In the second one there's an explanation of why application cache layers suck, why nerly every php application does caching in the less productive way and how you benefit from HTTP cache from this point of view.

phpcachesymfony2
Controlled Code
Delegated Code
The framework / library code
Controlled Code
Delegated Code Controlled Code
Delegated Code
Change
Controlled Code

Recommended for you

Bacbkone js
Bacbkone jsBacbkone js
Bacbkone js

Backbone.js is a JavaScript framework that aims to solve issues with messy JavaScript code by implementing an MVC pattern and object-oriented principles, providing structure through core concepts like Models for data storage, Collections for grouping Models, and Views for rendering display logic, as well as a Router for navigation. It is lightweight at only 6kb and supports RESTful JSON APIs and event-driven programming.

PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2

By the sum of PHPUnit assertion power and Symfony2 functional testing tools the developer can obtain a deep control on the developed application. Here you can find some suggestions on how to leverage that power.

symfony2 phpunit testing profiler paypal
Zend framework service
Zend framework serviceZend framework service
Zend framework service

Showing how to use an API layer within Zend Framework and still use the full MVC structure to keep your apps

dpc11zfservice
Delegated Code
Change
Controlled Code
Delegated Code
Change
Controlled Code
Owned Code Delegated Code
Change
Controlled Code
Owned Code Delegated Code
Change
Controlled Code

Recommended for you

Zend framework service
Zend framework serviceZend framework service
Zend framework service

This document discusses using Zend Framework components to create web services. It describes creating an API class to move logic out of controllers and structure the application. The API class is used to build XML-RPC, SOAP, and REST servers and clients to access a timesheet application. DocBlocks are recommended to document the API. Moving functionality to a reusable API library saves development time and makes the application more maintainable and testable.

zfdpc11service
Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejs

This document provides an overview of using the Backbone.js framework for client-side MVC applications. It discusses why Backbone is useful for structuring JavaScript applications, its core architecture including models, collections, views and routers. It also provides examples of how to convert jQuery code to use a Backbone-based approach and lists some real-world applications that use Backbone.

backbonejs
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From Iusethis

practical examples of how I used Catalyst and DBIx::Class to write http://osx.iusethis.com/, a social-software site for software.

Owned Code Delegated Code
Change
Controlled Code
Owned Code Delegated Code Controlled Code
Owned Code Controlled Code
– An engineer
“Ah, to hell with that!”

Recommended for you

Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy

These are slides to my presentation on Virtual Madness - the virtual machine management platform at Etsy.

javascriptetsymarionette
前端MVC 豆瓣说
前端MVC 豆瓣说前端MVC 豆瓣说
前端MVC 豆瓣说

The document describes the Backbone.js framework and how it can be used to build single page applications. It explains the core components of Backbone - Models, Collections, Views and Routers. It provides examples of initializing a Backbone application, defining models and collections, creating views to render data, and setting up routes and navigation. It also covers events, templating, and best practices for structuring Backbone code into separate JavaScript files for models, collections, views etc.

Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners

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.

doctrinesymfonyorm
Owned Code
Owned Code
Change
Owned Code
ENTERPRISE
FRAMEWORK

Recommended for you

Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenarios

This document discusses why CRUD (Create, Read, Update, Delete) is generally not a good approach for designing application code and APIs. It argues that entities should follow real business rules and scenarios rather than allowing arbitrary setting of attributes. Setters in particular are problematic as they don't map to real-world actions and don't enforce data integrity. The document recommends focusing on expressive methods that model real use cases rather than generic update operations. It also discusses how to add a CRUD layer on top of an internal domain model if needed while still maintaining encapsulation. The key takeaway is that applications should be designed around rich domain objects and real business behaviors rather than simple data access patterns.

Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11

The document discusses unit testing Zend Framework applications. It provides an overview of setting up PHPUnit for testing, including creating a phpunit.xml file and TestHelper bootstrap file. It also discusses testing Zend Forms and Models, including writing tests to validate form data and test that models are empty on construction. Code examples are provided for writing tests for a CommentForm and CommentModel class.

zftek11phpunit
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps

In 2010, I told everyone how to start unit testing Zend Framework applications. In 2011, let’s take this a step further by testing services, work flows and performance. Looking to raise the bar on quality? Let this talk be the push you need to improve your Zend Framework projects.

phpzendconzend framework
Min-Maxing Software Costs
Controlled Code
Your first feature
Controlled Code
Controlled Code
Your second feature

Recommended for you

Things I Believe Now That I'm Old
Things I Believe Now That I'm OldThings I Believe Now That I'm Old
Things I Believe Now That I'm Old

Closing keynote, as presented at Codemotion 2014, LaraconEU 2014, Redevelop 2014, CodeConnexx 2013 and PHP North East 2014. This presentation makes a reference to a reading list I received. For those interested, the release consists of most of the general classics, such as Gang Of Four "Design Patterns", The Pragmatic Programmer, Structure and Interpretation of Computer Programs, Domain Driven Design and a few others. The actual list remains tucked away in a box somewhere.

#ccxx13phpcodeconnexx
Tidy Up Your Code
Tidy Up Your CodeTidy Up Your Code
Tidy Up Your Code

The document discusses several ways to write readable code, including using proper formatting and spacing, clear and consistent naming conventions, modular code structure, and refactoring techniques. It provides examples of good code formatting practices like adding spacing before returns, arranging variables consistently, using descriptive names instead of abbreviations, and prefixing variables and methods for clarity. The document emphasizes that readable code clearly communicates intent to readers.

phpwordpresslaravel
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using Codeception

You must’ve heard of Unit testing… If not, then this talk is definitely for you! If you do know Unit testing, you probably ran at some point into a hurdle: “Where do I start?” And despite your best efforts, you end up not having enough tests for your application – Then that change request comes in, requiring you to change that very same complex piece of code for which you are lacking tests! How do you going refactor while maintaining all those ‘undocumented’ business rules? This talk will show how Codeception can be leveraged to refactor the visuals aspects of an application, maintaining backwards compatibility on API changes and even assist in moving to a whole different server infrastructure.

codeceptionapi testingtesting
Controlled Code
Controlled Code
Change
Controlled Code
Change
Controlled Code
Change

Recommended for you

(PHPers Wrocław #5) How to write valuable unit test?
(PHPers Wrocław #5) How to write valuable unit test?(PHPers Wrocław #5) How to write valuable unit test?
(PHPers Wrocław #5) How to write valuable unit test?

Tests should focus on validating behavior and outcomes rather than implementation details. Avoid testing private methods or mocking them, as this tests implementation rather than public interface. Follow a test-driven development process of red-green-refactor to incrementally develop testable code and avoid large untested code blocks. Workshops were offered to help learn techniques for writing high-quality unit tests.

phpersphptesting
Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)

The document discusses how Symfony 1.2 supports RESTful routes out of the box. It provides examples of how to configure routes to support different HTTP methods like GET, POST, PUT, DELETE. It also describes how to create custom route classes to support additional route matching and generation behaviors, like domain routing based on subdomains. Overall, the document shows how Symfony 1.2 allows developers to easily create RESTful applications by mapping URLs to controller actions and resources in a RESTful way.

phpsymfony
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux

The document discusses unit testing Zend Framework applications. It begins by explaining the importance of testing and some common excuses for not testing. It then provides examples of setting up PHPUnit configuration and bootstrap files for testing Zend Framework applications. The document demonstrates how to write tests for Zend Forms and models, including testing with both valid and invalid data. It shows how to modify models to add validation filters and validators.

unit testingphpbeneluxzend framework
– A business person
“Why does it always take so long?”
Controlled CodeOwned Code
Change
Controlled CodeOwned Code
Change
Controlled CodeOwned Code
Change

Recommended for you

50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes

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!

phplaraveltricks
Coordinate Systems in FME 101 - Webinar Slides
Coordinate Systems in FME 101 - Webinar SlidesCoordinate Systems in FME 101 - Webinar Slides
Coordinate Systems in FME 101 - Webinar Slides

If you’ve ever had to analyze a map or GPS data, chances are you’ve encountered and even worked with coordinate systems. As historical data continually updates through GPS, understanding coordinate systems is increasingly crucial. However, not everyone knows why they exist or how to effectively use them for data-driven insights. During this webinar, you’ll learn exactly what coordinate systems are and how you can use FME to maintain and transform your data’s coordinate systems in an easy-to-digest way, accurately representing the geographical space that it exists within. During this webinar, you will have the chance to: - Enhance Your Understanding: Gain a clear overview of what coordinate systems are and their value - Learn Practical Applications: Why we need datams and projections, plus units between coordinate systems - Maximize with FME: Understand how FME handles coordinate systems, including a brief summary of the 3 main reprojectors - Custom Coordinate Systems: Learn how to work with FME and coordinate systems beyond what is natively supported - Look Ahead: Gain insights into where FME is headed with coordinate systems in the future Don’t miss the opportunity to improve the value you receive from your coordinate system data, ultimately allowing you to streamline your data analysis and maximize your time. See you there!

Quality Patents: Patents That Stand the Test of Time
Quality Patents: Patents That Stand the Test of TimeQuality Patents: Patents That Stand the Test of Time
Quality Patents: Patents That Stand the Test of Time

Is your patent a vanity piece of paper for your office wall? Or is it a reliable, defendable, assertable, property right? The difference is often quality. Is your patent simply a transactional cost and a large pile of legal bills for your startup? Or is it a leverageable asset worthy of attracting precious investment dollars, worth its cost in multiples of valuation? The difference is often quality. Is your patent application only good enough to get through the examination process? Or has it been crafted to stand the tests of time and varied audiences if you later need to assert that document against an infringer, find yourself litigating with it in an Article 3 Court at the hands of a judge and jury, God forbid, end up having to defend its validity at the PTAB, or even needing to use it to block pirated imports at the International Trade Commission? The difference is often quality. Quality will be our focus for a good chunk of the remainder of this season. What goes into a quality patent, and where possible, how do you get it without breaking the bank? ** Episode Overview ** In this first episode of our quality series, Kristen Hansen and the panel discuss: ⦿ What do we mean when we say patent quality? ⦿ Why is patent quality important? ⦿ How to balance quality and budget ⦿ The importance of searching, continuations, and draftsperson domain expertise ⦿ Very practical tips, tricks, examples, and Kristen’s Musts for drafting quality applications https://www.aurorapatents.com/patently-strategic-podcast.html

patentspatent applicationpatent prosecution
Controlled CodeOwned Code
Owned Code
CONTROL HAS COST
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation Cost of Change Cost of Control

Recommended for you

Mitigating the Impact of State Management in Cloud Stream Processing Systems
Mitigating the Impact of State Management in Cloud Stream Processing SystemsMitigating the Impact of State Management in Cloud Stream Processing Systems
Mitigating the Impact of State Management in Cloud Stream Processing Systems

Stream processing is a crucial component of modern data infrastructure, but constructing an efficient and scalable stream processing system can be challenging. Decoupling compute and storage architecture has emerged as an effective solution to these challenges, but it can introduce high latency issues, especially when dealing with complex continuous queries that necessitate managing extra-large internal states. In this talk, we focus on addressing the high latency issues associated with S3 storage in stream processing systems that employ a decoupled compute and storage architecture. We delve into the root causes of latency in this context and explore various techniques to minimize the impact of S3 latency on stream processing performance. Our proposed approach is to implement a tiered storage mechanism that leverages a blend of high-performance and low-cost storage tiers to reduce data movement between the compute and storage layers while maintaining efficient processing. Throughout the talk, we will present experimental results that demonstrate the effectiveness of our approach in mitigating the impact of S3 latency on stream processing. By the end of the talk, attendees will have gained insights into how to optimize their stream processing systems for reduced latency and improved cost-efficiency.

[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf
[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf
[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf

Kief Morris rethinks the infrastructure code delivery lifecycle, advocating for a shift towards composable infrastructure systems. We should shift to designing around deployable components rather than code modules, use more useful levels of abstraction, and drive design and deployment from applications rather than bottom-up, monolithic architecture and delivery.

infrastructure as codeclouddevops
Manual | Product | Research Presentation
Manual | Product | Research PresentationManual | Product | Research Presentation
Manual | Product | Research Presentation

Manual Method of Product Research | Helium10 | MBS RETRIEVER

product researchhelium10 | mbs retriever
CONTROL
IS A LIMITER FOR A
COST OF CHANGE
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation Cost of Change Cost of Control
CONTROLLING
TOO FEW
TOO LATE
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation Cost of Change Cost of Control

Recommended for you

Best Practices for Effectively Running dbt in Airflow.pdf
Best Practices for Effectively Running dbt in Airflow.pdfBest Practices for Effectively Running dbt in Airflow.pdf
Best Practices for Effectively Running dbt in Airflow.pdf

As a popular open-source library for analytics engineering, dbt is often used in combination with Airflow. Orchestrating and executing dbt models as DAGs ensures an additional layer of control over tasks, observability, and provides a reliable, scalable environment to run dbt models. This webinar will cover a step-by-step guide to Cosmos, an open source package from Astronomer that helps you easily run your dbt Core projects as Airflow DAGs and Task Groups, all with just a few lines of code. We’ll walk through: - Standard ways of running dbt (and when to utilize other methods) - How Cosmos can be used to run and visualize your dbt projects in Airflow - Common challenges and how to address them, including performance, dependency conflicts, and more - How running dbt projects in Airflow helps with cost optimization Webinar given on 9 July 2024

apache airflowdbtdbt-core
Recent Advancements in the NIST-JARVIS Infrastructure
Recent Advancements in the NIST-JARVIS InfrastructureRecent Advancements in the NIST-JARVIS Infrastructure
Recent Advancements in the NIST-JARVIS Infrastructure

Recent advancements in the NIST-JARVIS infrastructure: JARVIS-Overview, JARVIS-DFT, AtomGPT, ALIGNN, JARVIS-Leaderboard

jarvisjarvis-dftalignn
WPRiders Company Presentation Slide Deck
WPRiders Company Presentation Slide DeckWPRiders Company Presentation Slide Deck
WPRiders Company Presentation Slide Deck

YOUR RELIABLE WEB DESIGN & DEVELOPMENT TEAM — FOR LASTING SUCCESS WPRiders is a web development company specialized in WordPress and WooCommerce websites and plugins for customers around the world. The company is headquartered in Bucharest, Romania, but our team members are located all over the world. Our customers are primarily from the US and Western Europe, but we have clients from Australia, Canada and other areas as well. Some facts about WPRiders and why we are one of the best firms around: More than 700 five-star reviews! You can check them here. 1500 WordPress projects delivered. We respond 80% faster than other firms! Data provided by Freshdesk. We’ve been in business since 2015. We are located in 7 countries and have 22 team members. With so many projects delivered, our team knows what works and what doesn’t when it comes to WordPress and WooCommerce. Our team members are: - highly experienced developers (employees & contractors with 5 -10+ years of experience), - great designers with an eye for UX/UI with 10+ years of experience - project managers with development background who speak both tech and non-tech - QA specialists - Conversion Rate Optimisation - CRO experts They are all working together to provide you with the best possible service. We are passionate about WordPress, and we love creating custom solutions that help our clients achieve their goals. At WPRiders, we are committed to building long-term relationships with our clients. We believe in accountability, in doing the right thing, as well as in transparency and open communication. You can read more about WPRiders on the About us page.

web development agencywpriderswordpress development
CONTROLLING
TOO MUCH
TOO EARLY
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation Cost of Change Cost of Control
OWNING MORE
THANYOU CONTROL
IS UNSUSTAINABLE
CONTROLLING
EVERYTHING
IS EXPENSIVE

Recommended for you

20240702 Présentation Plateforme GenAI.pdf
20240702 Présentation Plateforme GenAI.pdf20240702 Présentation Plateforme GenAI.pdf
20240702 Présentation Plateforme GenAI.pdf

Support en anglais diffusé lors de l'événement 100% IA organisé dans les locaux parisiens d'Iguane Solutions, le mardi 2 juillet 2024 : - Présentation de notre plateforme IA plug and play : ses fonctionnalités avancées, telles que son interface utilisateur intuitive, son copilot puissant et des outils de monitoring performants. - REX client : Cyril Janssens, CTO d’ easybourse, partage son expérience d’utilisation de notre plateforme IA plug & play.

genaicloudrgpd
Choose our Linux Web Hosting for a seamless and successful online presence
Choose our Linux Web Hosting for a seamless and successful online presenceChoose our Linux Web Hosting for a seamless and successful online presence
Choose our Linux Web Hosting for a seamless and successful online presence

Our Linux Web Hosting plans offer unbeatable performance, security, and scalability, ensuring your website runs smoothly and efficiently. Visit- https://onliveserver.com/linux-web-hosting/

cheap linux hosting
Password Rotation in 2024 is still Relevant
Password Rotation in 2024 is still RelevantPassword Rotation in 2024 is still Relevant
Password Rotation in 2024 is still Relevant

Password Rotation in 2024 is still Relevant

passwordmanagementrotation
MIN-MAXING
SOFTWARE COSTS
4 RULES OF MIN-MAXING
1. Begin from owning nothing ( )
2. Take ownership reluctantly ( )
3. Control everything you own ( )
4. Continuously reassess your control ( )
HEALTHY YOUNG PROJECT
Owned Code Delegated Code Controlled Code
UNHEALTHY YOUNG PROJECT
Owned Code Delegated Code Controlled Code

Recommended for you

The Rise of Supernetwork Data Intensive Computing
The Rise of Supernetwork Data Intensive ComputingThe Rise of Supernetwork Data Intensive Computing
The Rise of Supernetwork Data Intensive Computing

Invited Remote Lecture to SC21 The International Conference for High Performance Computing, Networking, Storage, and Analysis St. Louis, Missouri November 18, 2021

distributed supercomputerdistributed machine learning
Fluttercon 2024: Showing that you care about security - OpenSSF Scorecards fo...
Fluttercon 2024: Showing that you care about security - OpenSSF Scorecards fo...Fluttercon 2024: Showing that you care about security - OpenSSF Scorecards fo...
Fluttercon 2024: Showing that you care about security - OpenSSF Scorecards fo...

Have you noticed the OpenSSF Scorecard badges on the official Dart and Flutter repos? It's Google's way of showing that they care about security. Practices such as pinning dependencies, branch protection, required reviews, continuous integration tests etc. are measured to provide a score and accompanying badge. You can do the same for your projects, and this presentation will show you how, with an emphasis on the unique challenges that come up when working with Dart and Flutter. The session will provide a walkthrough of the steps involved in securing a first repository, and then what it takes to repeat that process across an organization with multiple repos. It will also look at the ongoing maintenance involved once scorecards have been implemented, and how aspects of that maintenance can be better automated to minimize toil.

dartflutteropenssf
How RPA Help in the Transportation and Logistics Industry.pptx
How RPA Help in the Transportation and Logistics Industry.pptxHow RPA Help in the Transportation and Logistics Industry.pptx
How RPA Help in the Transportation and Logistics Industry.pptx

Revolutionize your transportation processes with our cutting-edge RPA software. Automate repetitive tasks, reduce costs, and enhance efficiency in the logistics sector with our advanced solutions.

rpa in transportationrpa in transportation industryrpa in transportation sector
UNHEALTHY YOUNG PROJECT
Owned Code Delegated Code Controlled Code
HEALTHY MATURE PROJECT
Owned Code Delegated Code Controlled Code
UNHEALTHY “MATURE” PROJECT
Owned Code Delegated Code Controlled Code
UNHEALTHY “MATURE” PROJECT
Owned Code Delegated Code Controlled Code

Recommended for you

UiPath Community Day Kraków: Devs4Devs Conference
UiPath Community Day Kraków: Devs4Devs ConferenceUiPath Community Day Kraków: Devs4Devs Conference
UiPath Community Day Kraków: Devs4Devs Conference

We are honored to launch and host this event for our UiPath Polish Community, with the help of our partners - Proservartner! We certainly hope we have managed to spike your interest in the subjects to be presented and the incredible networking opportunities at hand, too! Check out our proposed agenda below 👇👇 08:30 ☕ Welcome coffee (30') 09:00 Opening note/ Intro to UiPath Community (10') Cristina Vidu, Global Manager, Marketing Community @UiPath Dawid Kot, Digital Transformation Lead @Proservartner 09:10 Cloud migration - Proservartner & DOVISTA case study (30') Marcin Drozdowski, Automation CoE Manager @DOVISTA Pawel Kamiński, RPA developer @DOVISTA Mikolaj Zielinski, UiPath MVP, Senior Solutions Engineer @Proservartner 09:40 From bottlenecks to breakthroughs: Citizen Development in action (25') Pawel Poplawski, Director, Improvement and Automation @McCormick & Company Michał Cieślak, Senior Manager, Automation Programs @McCormick & Company 10:05 Next-level bots: API integration in UiPath Studio (30') Mikolaj Zielinski, UiPath MVP, Senior Solutions Engineer @Proservartner 10:35 ☕ Coffee Break (15') 10:50 Document Understanding with my RPA Companion (45') Ewa Gruszka, Enterprise Sales Specialist, AI & ML @UiPath 11:35 Power up your Robots: GenAI and GPT in REFramework (45') Krzysztof Karaszewski, Global RPA Product Manager 12:20 🍕 Lunch Break (1hr) 13:20 From Concept to Quality: UiPath Test Suite for AI-powered Knowledge Bots (30') Kamil Miśko, UiPath MVP, Senior RPA Developer @Zurich Insurance 13:50 Communications Mining - focus on AI capabilities (30') Thomasz Wierzbicki, Business Analyst @Office Samurai 14:20 Polish MVP panel: Insights on MVP award achievements and career profiling

#uipathcommunity#automation#automationdeveloper
BLOCKCHAIN FOR DUMMIES: GUIDEBOOK FOR ALL
BLOCKCHAIN FOR DUMMIES: GUIDEBOOK FOR ALLBLOCKCHAIN FOR DUMMIES: GUIDEBOOK FOR ALL
BLOCKCHAIN FOR DUMMIES: GUIDEBOOK FOR ALL

Blockchain technology is transforming industries and reshaping the way we conduct business, manage data, and secure transactions. Whether you're new to blockchain or looking to deepen your knowledge, our guidebook, "Blockchain for Dummies", is your ultimate resource.

blockchainweb3blockchain technology
Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...
Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...
Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...

Today’s digitally connected world presents a wide range of security challenges for enterprises. Insider security threats are particularly noteworthy because they have the potential to cause significant harm. Unlike external threats, insider risks originate from within the company, making them more subtle and challenging to identify. This blog aims to provide a comprehensive understanding of insider security threats, including their types, examples, effects, and mitigation techniques.

insider securitycybersecurity threatsenterprise security
1. BEGIN
FROM OWNING
NOTHING
2.TAKE
OWNERSHIP
RELUCTANTLY
3. CONTROL
EVERYTHING
YOU OWN
4. CONTINUOUSLY
REASSESSYOUR
CONTROL

Recommended for you

Cookies program to display the information though cookie creation
Cookies program to display the information though cookie creationCookies program to display the information though cookie creation
Cookies program to display the information though cookie creation

Java Servlet programs

WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf
WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdfWhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf
WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf

Profile portofolio

Quantum Communications Q&A with Gemini LLM
Quantum Communications Q&A with Gemini LLMQuantum Communications Q&A with Gemini LLM
Quantum Communications Q&A with Gemini LLM

Quantum Communications Q&A with Gemini LLM. These are based on Shannon's Noisy channel Theorem and offers how the classical theory applies to the quantum world.

quantum communicationsshannon's channel theoremclassical theory
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation Cost of Change Cost of Control
Control everything you write.
Avoid writing anything.
Deliver business impact,
not software.
THANK YOU
FORYOURTIME!
Konstantin K.
@everzet

Recommended for you

More Related Content

What's hot

Decoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDDDecoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDD
Aleix Vergés
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et Pimple
Hugo Hamon
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il cliente
Leonardo Proietti
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
Hugo Hamon
 
Models and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsModels and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and Hobgoblins
Ross Tuck
 
Mocking Demystified
Mocking DemystifiedMocking Demystified
Mocking Demystified
Marcello Duarte
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns
Hugo Hamon
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful software
Jorn Oomen
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
Hugo Hamon
 
Rich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationRich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 Application
Kirill Chebunin
 
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolve
XSolve
 
Command Bus To Awesome Town
Command Bus To Awesome TownCommand Bus To Awesome Town
Command Bus To Awesome Town
Ross Tuck
 
Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web services
Michelangelo van Dam
 
Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!
Kacper Gunia
 
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersPHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4Developers
Kacper Gunia
 
CQRS and Event Sourcing in a Symfony application
CQRS and Event Sourcing in a Symfony applicationCQRS and Event Sourcing in a Symfony application
CQRS and Event Sourcing in a Symfony application
Samuel ROZE
 
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in action
Jace Ju
 
Forget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowForget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers Cracow
Kacper Gunia
 
Adding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy ApplicationsAdding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy Applications
Sam Hennessy
 
November Camp - Spec BDD with PHPSpec 2
November Camp - Spec BDD with PHPSpec 2November Camp - Spec BDD with PHPSpec 2
November Camp - Spec BDD with PHPSpec 2
Kacper Gunia
 

What's hot (20)

Decoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDDDecoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDD
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et Pimple
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il cliente
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
 
Models and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsModels and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and Hobgoblins
 
Mocking Demystified
Mocking DemystifiedMocking Demystified
Mocking Demystified
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful software
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
 
Rich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationRich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 Application
 
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolve
 
Command Bus To Awesome Town
Command Bus To Awesome TownCommand Bus To Awesome Town
Command Bus To Awesome Town
 
Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web services
 
Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!
 
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersPHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4Developers
 
CQRS and Event Sourcing in a Symfony application
CQRS and Event Sourcing in a Symfony applicationCQRS and Event Sourcing in a Symfony application
CQRS and Event Sourcing in a Symfony application
 
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in action
 
Forget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowForget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers Cracow
 
Adding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy ApplicationsAdding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy Applications
 
November Camp - Spec BDD with PHPSpec 2
November Camp - Spec BDD with PHPSpec 2November Camp - Spec BDD with PHPSpec 2
November Camp - Spec BDD with PHPSpec 2
 

Viewers also liked

Moving away from legacy code with BDD
Moving away from legacy code with BDDMoving away from legacy code with BDD
Moving away from legacy code with BDD
Konstantin Kudryashov
 
Modern Agile Project Toolbox
Modern Agile Project ToolboxModern Agile Project Toolbox
Modern Agile Project Toolbox
Konstantin Kudryashov
 
Moving away from legacy code (AgileCymru)
Moving away from legacy code  (AgileCymru)Moving away from legacy code  (AgileCymru)
Moving away from legacy code (AgileCymru)
Konstantin Kudryashov
 
Taking back BDD
Taking back BDDTaking back BDD
Taking back BDD
Konstantin Kudryashov
 
BDD by example
BDD by exampleBDD by example
BDD by example
Xavier Fornés Arrabal
 
Enabling agile devliery through enabling BDD in PHP projects
Enabling agile devliery through enabling BDD in PHP projectsEnabling agile devliery through enabling BDD in PHP projects
Enabling agile devliery through enabling BDD in PHP projects
Konstantin Kudryashov
 
Modern Project Toolbox
Modern Project ToolboxModern Project Toolbox
Modern Project Toolbox
Konstantin Kudryashov
 
Being effective with legacy projects
Being effective with legacy projectsBeing effective with legacy projects
Being effective with legacy projects
Konstantin Kudryashov
 
BDD в PHP с Behat и Mink
BDD в PHP с Behat и MinkBDD в PHP с Behat и Mink
BDD в PHP с Behat и Mink
Konstantin Kudryashov
 
Bridging The Communication Gap, Fast
Bridging The Communication Gap, Fast Bridging The Communication Gap, Fast
Bridging The Communication Gap, Fast
Konstantin Kudryashov
 
Moving away from legacy code with BDD
Moving away from legacy code with BDDMoving away from legacy code with BDD
Moving away from legacy code with BDD
Konstantin Kudryashov
 

Viewers also liked (12)

Moving away from legacy code with BDD
Moving away from legacy code with BDDMoving away from legacy code with BDD
Moving away from legacy code with BDD
 
Modern Agile Project Toolbox
Modern Agile Project ToolboxModern Agile Project Toolbox
Modern Agile Project Toolbox
 
Moving away from legacy code (AgileCymru)
Moving away from legacy code  (AgileCymru)Moving away from legacy code  (AgileCymru)
Moving away from legacy code (AgileCymru)
 
Taking back BDD
Taking back BDDTaking back BDD
Taking back BDD
 
BDD by example
BDD by exampleBDD by example
BDD by example
 
Enabling agile devliery through enabling BDD in PHP projects
Enabling agile devliery through enabling BDD in PHP projectsEnabling agile devliery through enabling BDD in PHP projects
Enabling agile devliery through enabling BDD in PHP projects
 
Modern Project Toolbox
Modern Project ToolboxModern Project Toolbox
Modern Project Toolbox
 
Being effective with legacy projects
Being effective with legacy projectsBeing effective with legacy projects
Being effective with legacy projects
 
BDD в PHP с Behat и Mink
BDD в PHP с Behat и MinkBDD в PHP с Behat и Mink
BDD в PHP с Behat и Mink
 
BDD для PHP проектов
BDD для PHP проектовBDD для PHP проектов
BDD для PHP проектов
 
Bridging The Communication Gap, Fast
Bridging The Communication Gap, Fast Bridging The Communication Gap, Fast
Bridging The Communication Gap, Fast
 
Moving away from legacy code with BDD
Moving away from legacy code with BDDMoving away from legacy code with BDD
Moving away from legacy code with BDD
 

Similar to Min-Maxing Software Costs

Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
 Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011 Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
Alessandro Nadalin
 
Bacbkone js
Bacbkone jsBacbkone js
PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2
eugenio pombi
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
Michelangelo van Dam
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
Michelangelo van Dam
 
Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejs
Nick Lee
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From Iusethis
Marcus Ramberg
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
Nishan Subedi
 
前端MVC 豆瓣说
前端MVC 豆瓣说前端MVC 豆瓣说
前端MVC 豆瓣说
Ting Lv
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
Jonathan Wage
 
Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenarios
Divante
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
Michelangelo van Dam
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
Michelangelo van Dam
 
Things I Believe Now That I'm Old
Things I Believe Now That I'm OldThings I Believe Now That I'm Old
Things I Believe Now That I'm Old
Ross Tuck
 
Tidy Up Your Code
Tidy Up Your CodeTidy Up Your Code
Tidy Up Your Code
Abbas Ali
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using Codeception
Jeroen van Dijk
 
(PHPers Wrocław #5) How to write valuable unit test?
(PHPers Wrocław #5) How to write valuable unit test?(PHPers Wrocław #5) How to write valuable unit test?
(PHPers Wrocław #5) How to write valuable unit test?
RST Software Masters
 
Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)
Fabien Potencier
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
Michelangelo van Dam
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes
Azim Kurt
 

Similar to Min-Maxing Software Costs (20)

Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
 Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011 Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
 
Bacbkone js
Bacbkone jsBacbkone js
Bacbkone js
 
PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
 
Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejs
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From Iusethis
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 
前端MVC 豆瓣说
前端MVC 豆瓣说前端MVC 豆瓣说
前端MVC 豆瓣说
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenarios
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Things I Believe Now That I'm Old
Things I Believe Now That I'm OldThings I Believe Now That I'm Old
Things I Believe Now That I'm Old
 
Tidy Up Your Code
Tidy Up Your CodeTidy Up Your Code
Tidy Up Your Code
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using Codeception
 
(PHPers Wrocław #5) How to write valuable unit test?
(PHPers Wrocław #5) How to write valuable unit test?(PHPers Wrocław #5) How to write valuable unit test?
(PHPers Wrocław #5) How to write valuable unit test?
 
Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes
 

Recently uploaded

Coordinate Systems in FME 101 - Webinar Slides
Coordinate Systems in FME 101 - Webinar SlidesCoordinate Systems in FME 101 - Webinar Slides
Coordinate Systems in FME 101 - Webinar Slides
Safe Software
 
Quality Patents: Patents That Stand the Test of Time
Quality Patents: Patents That Stand the Test of TimeQuality Patents: Patents That Stand the Test of Time
Quality Patents: Patents That Stand the Test of Time
Aurora Consulting
 
Mitigating the Impact of State Management in Cloud Stream Processing Systems
Mitigating the Impact of State Management in Cloud Stream Processing SystemsMitigating the Impact of State Management in Cloud Stream Processing Systems
Mitigating the Impact of State Management in Cloud Stream Processing Systems
ScyllaDB
 
[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf
[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf
[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf
Kief Morris
 
Manual | Product | Research Presentation
Manual | Product | Research PresentationManual | Product | Research Presentation
Manual | Product | Research Presentation
welrejdoall
 
Best Practices for Effectively Running dbt in Airflow.pdf
Best Practices for Effectively Running dbt in Airflow.pdfBest Practices for Effectively Running dbt in Airflow.pdf
Best Practices for Effectively Running dbt in Airflow.pdf
Tatiana Al-Chueyr
 
Recent Advancements in the NIST-JARVIS Infrastructure
Recent Advancements in the NIST-JARVIS InfrastructureRecent Advancements in the NIST-JARVIS Infrastructure
Recent Advancements in the NIST-JARVIS Infrastructure
KAMAL CHOUDHARY
 
WPRiders Company Presentation Slide Deck
WPRiders Company Presentation Slide DeckWPRiders Company Presentation Slide Deck
WPRiders Company Presentation Slide Deck
Lidia A.
 
20240702 Présentation Plateforme GenAI.pdf
20240702 Présentation Plateforme GenAI.pdf20240702 Présentation Plateforme GenAI.pdf
20240702 Présentation Plateforme GenAI.pdf
Sally Laouacheria
 
Choose our Linux Web Hosting for a seamless and successful online presence
Choose our Linux Web Hosting for a seamless and successful online presenceChoose our Linux Web Hosting for a seamless and successful online presence
Choose our Linux Web Hosting for a seamless and successful online presence
rajancomputerfbd
 
Password Rotation in 2024 is still Relevant
Password Rotation in 2024 is still RelevantPassword Rotation in 2024 is still Relevant
Password Rotation in 2024 is still Relevant
Bert Blevins
 
The Rise of Supernetwork Data Intensive Computing
The Rise of Supernetwork Data Intensive ComputingThe Rise of Supernetwork Data Intensive Computing
The Rise of Supernetwork Data Intensive Computing
Larry Smarr
 
Fluttercon 2024: Showing that you care about security - OpenSSF Scorecards fo...
Fluttercon 2024: Showing that you care about security - OpenSSF Scorecards fo...Fluttercon 2024: Showing that you care about security - OpenSSF Scorecards fo...
Fluttercon 2024: Showing that you care about security - OpenSSF Scorecards fo...
Chris Swan
 
How RPA Help in the Transportation and Logistics Industry.pptx
How RPA Help in the Transportation and Logistics Industry.pptxHow RPA Help in the Transportation and Logistics Industry.pptx
How RPA Help in the Transportation and Logistics Industry.pptx
SynapseIndia
 
UiPath Community Day Kraków: Devs4Devs Conference
UiPath Community Day Kraków: Devs4Devs ConferenceUiPath Community Day Kraków: Devs4Devs Conference
UiPath Community Day Kraków: Devs4Devs Conference
UiPathCommunity
 
BLOCKCHAIN FOR DUMMIES: GUIDEBOOK FOR ALL
BLOCKCHAIN FOR DUMMIES: GUIDEBOOK FOR ALLBLOCKCHAIN FOR DUMMIES: GUIDEBOOK FOR ALL
BLOCKCHAIN FOR DUMMIES: GUIDEBOOK FOR ALL
Liveplex
 
Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...
Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...
Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...
Bert Blevins
 
Cookies program to display the information though cookie creation
Cookies program to display the information though cookie creationCookies program to display the information though cookie creation
Cookies program to display the information though cookie creation
shanthidl1
 
WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf
WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdfWhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf
WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf
ArgaBisma
 
Quantum Communications Q&A with Gemini LLM
Quantum Communications Q&A with Gemini LLMQuantum Communications Q&A with Gemini LLM
Quantum Communications Q&A with Gemini LLM
Vijayananda Mohire
 

Recently uploaded (20)

Coordinate Systems in FME 101 - Webinar Slides
Coordinate Systems in FME 101 - Webinar SlidesCoordinate Systems in FME 101 - Webinar Slides
Coordinate Systems in FME 101 - Webinar Slides
 
Quality Patents: Patents That Stand the Test of Time
Quality Patents: Patents That Stand the Test of TimeQuality Patents: Patents That Stand the Test of Time
Quality Patents: Patents That Stand the Test of Time
 
Mitigating the Impact of State Management in Cloud Stream Processing Systems
Mitigating the Impact of State Management in Cloud Stream Processing SystemsMitigating the Impact of State Management in Cloud Stream Processing Systems
Mitigating the Impact of State Management in Cloud Stream Processing Systems
 
[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf
[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf
[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf
 
Manual | Product | Research Presentation
Manual | Product | Research PresentationManual | Product | Research Presentation
Manual | Product | Research Presentation
 
Best Practices for Effectively Running dbt in Airflow.pdf
Best Practices for Effectively Running dbt in Airflow.pdfBest Practices for Effectively Running dbt in Airflow.pdf
Best Practices for Effectively Running dbt in Airflow.pdf
 
Recent Advancements in the NIST-JARVIS Infrastructure
Recent Advancements in the NIST-JARVIS InfrastructureRecent Advancements in the NIST-JARVIS Infrastructure
Recent Advancements in the NIST-JARVIS Infrastructure
 
WPRiders Company Presentation Slide Deck
WPRiders Company Presentation Slide DeckWPRiders Company Presentation Slide Deck
WPRiders Company Presentation Slide Deck
 
20240702 Présentation Plateforme GenAI.pdf
20240702 Présentation Plateforme GenAI.pdf20240702 Présentation Plateforme GenAI.pdf
20240702 Présentation Plateforme GenAI.pdf
 
Choose our Linux Web Hosting for a seamless and successful online presence
Choose our Linux Web Hosting for a seamless and successful online presenceChoose our Linux Web Hosting for a seamless and successful online presence
Choose our Linux Web Hosting for a seamless and successful online presence
 
Password Rotation in 2024 is still Relevant
Password Rotation in 2024 is still RelevantPassword Rotation in 2024 is still Relevant
Password Rotation in 2024 is still Relevant
 
The Rise of Supernetwork Data Intensive Computing
The Rise of Supernetwork Data Intensive ComputingThe Rise of Supernetwork Data Intensive Computing
The Rise of Supernetwork Data Intensive Computing
 
Fluttercon 2024: Showing that you care about security - OpenSSF Scorecards fo...
Fluttercon 2024: Showing that you care about security - OpenSSF Scorecards fo...Fluttercon 2024: Showing that you care about security - OpenSSF Scorecards fo...
Fluttercon 2024: Showing that you care about security - OpenSSF Scorecards fo...
 
How RPA Help in the Transportation and Logistics Industry.pptx
How RPA Help in the Transportation and Logistics Industry.pptxHow RPA Help in the Transportation and Logistics Industry.pptx
How RPA Help in the Transportation and Logistics Industry.pptx
 
UiPath Community Day Kraków: Devs4Devs Conference
UiPath Community Day Kraków: Devs4Devs ConferenceUiPath Community Day Kraków: Devs4Devs Conference
UiPath Community Day Kraków: Devs4Devs Conference
 
BLOCKCHAIN FOR DUMMIES: GUIDEBOOK FOR ALL
BLOCKCHAIN FOR DUMMIES: GUIDEBOOK FOR ALLBLOCKCHAIN FOR DUMMIES: GUIDEBOOK FOR ALL
BLOCKCHAIN FOR DUMMIES: GUIDEBOOK FOR ALL
 
Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...
Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...
Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...
 
Cookies program to display the information though cookie creation
Cookies program to display the information though cookie creationCookies program to display the information though cookie creation
Cookies program to display the information though cookie creation
 
WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf
WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdfWhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf
WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf
 
Quantum Communications Q&A with Gemini LLM
Quantum Communications Q&A with Gemini LLMQuantum Communications Q&A with Gemini LLM
Quantum Communications Q&A with Gemini LLM
 

Min-Maxing Software Costs

  • 6. SOFTWARE FORCES • Creation - Introduction of a brand new feature • Change - Business-driven modification of existing feature • Ownership - Physical capability to change a feature • Control - Capability to sustainably change a feature
  • 7. SOFTWARE COSTS 1. Cost of Creation 2. Cost of Change 3. Cost of Control
  • 9. Project Lifetime Beginning 3 months 6 months 9 months ... Cost of Creation
  • 11. $ bin/rails generate controller welcome index
  • 12. from django.contrib import admin from . import models admin.site.register(models.Article)
  • 13. package hello; import java.util.concurrent.atomic.AtomicLong; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class GreetingController { ... }
  • 15. Creation → Change Project Lifetime Beginning 3 months 6 months 9 months ... Cost of Creation
  • 16. Creation → Change Project Lifetime Beginning 3 months 6 months 9 months ... Cost of Creation Pure observation & personal experience
  • 17. Creation → Change Project Lifetime Beginning 3 months 6 months 9 months ... Cost of Creation Conventional Project
  • 18. Creation → Change Project Lifetime Beginning 3 months 6 months 9 months ... Cost of Creation Conventional Project Conventional Project
  • 19. Convention-based projects either die a hero or live long enough to see themselves become the villain.
  • 21. Project Lifetime Beginning 3 months 6 months 9 months ... Cost of Creation Cost of Change
  • 23. public function searchAction(Request $req) { $form = $this->createForm(new SearchQueryType, new SearchQuery); $normalizedOrderBys = $this->getNormalizedOrderBys($filteredOrderBys); $this->computeSearchQuery($req, $filteredOrderBys); if ($req->query->has('search_query')) { /** @var $solarium Solarium_Client */ $solarium = $this->get('solarium.client'); $select = $solarium->createSelect(); // configure dismax $dismax = $select->getDisMax(); $dismax->setQueryFields(array('name^4', 'description', 'tags', 'text', 'text_ngram', 'name_split^2')); if ($req->query->has('search_query')) { $form->bind($req); if ($form->isValid()) { $escapedQuery = $select->getHelper()->escapeTerm($form->getData()->getQuery()); $escapedQuery = preg_replace('/(^| )-(S)/', '$1-$2', $escapedQuery); $escapedQuery = preg_replace('/(^| )+(S)/', '$1+$2', $escapedQuery); if ((substr_count($escapedQuery, '"') % 2) == 0) { $escapedQuery = str_replace('"', '"', $escapedQuery); } $select->setQuery($escapedQuery); } } } elseif ($req->getRequestFormat() === 'json') { return JsonResponse::create(array( 'error' => 'Missing search query, example: ?q=example' ), 400)->setCallback($req->query->get('callback')); } return $this->render('SomeAppWebBundle:Web:search.html.twig'); }
  • 24. public function searchAction(Request $req) { $form = $this->createForm(new SearchQueryType, new SearchQuery); $normalizedOrderBys = $this->getNormalizedOrderBys($filteredOrderBys); $this->computeSearchQuery($req, $filteredOrderBys); if ($req->query->has('search_query')) { /** @var $solarium Solarium_Client */ $solarium = $this->get('solarium.client'); $select = $solarium->createSelect(); // configure dismax $dismax = $select->getDisMax(); $dismax->setQueryFields(array('name^4', 'description', 'tags', 'text', 'text_ngram', 'name_split^2')); if ($req->query->has('search_query')) { $form->bind($req); if ($form->isValid()) { $escapedQuery = $select->getHelper()->escapeTerm($form->getData()->getQuery()); $escapedQuery = preg_replace('/(^| )-(S)/', '$1-$2', $escapedQuery); $escapedQuery = preg_replace('/(^| )+(S)/', '$1+$2', $escapedQuery); if ((substr_count($escapedQuery, '"') % 2) == 0) { $escapedQuery = str_replace('"', '"', $escapedQuery); } $select->setQuery($escapedQuery); } } } elseif ($req->getRequestFormat() === 'json') { return JsonResponse::create(array( 'error' => 'Missing search query, example: ?q=example' ), 400)->setCallback($req->query->get('callback')); } return $this->render('SomeAppWebBundle:Web:search.html.twig'); }
  • 25. HOW LONG WOULD IT TAKETO ADD TAGS SUPPORT?
  • 26. public function searchAction(Request $req) { $form = $this->createForm(new SearchQueryType, new SearchQuery); $normalizedOrderBys = $this->getNormalizedOrderBys($filteredOrderBys); $this->computeSearchQuery($req, $filteredOrderBys); if ($req->query->has('search_query')) { /** @var $solarium Solarium_Client */ $solarium = $this->get('solarium.client'); $select = $solarium->createSelect(); // configure dismax $dismax = $select->getDisMax(); $dismax->setQueryFields(array('name^4', 'description', 'tags', 'text', 'text_ngram', 'name_split^2')); if ($req->query->has('search_query')) { $form->bind($req); if ($form->isValid()) { $escapedQuery = $select->getHelper()->escapeTerm($form->getData()->getQuery()); $escapedQuery = preg_replace('/(^| )-(S)/', '$1-$2', $escapedQuery); $escapedQuery = preg_replace('/(^| )+(S)/', '$1+$2', $escapedQuery); if ((substr_count($escapedQuery, '"') % 2) == 0) { $escapedQuery = str_replace('"', '"', $escapedQuery); } $select->setQuery($escapedQuery); } } } elseif ($req->getRequestFormat() === 'json') { return JsonResponse::create(array( 'error' => 'Missing search query, example: ?q=example' ), 400)->setCallback($req->query->get('callback')); } return $this->render('SomeAppWebBundle:Web:search.html.twig'); }
  • 27. public function searchAction(Request $req) { $form = $this->createForm(new SearchQueryType, new SearchQuery); $this->computeSearchQuery($req, $filteredOrderBys); $typeFilter = $req->query->get('type'); if ($req->query->has('search_query') || $typeFilter) { /** @var $solarium Solarium_Client */ $solarium = $this->get('solarium.client'); $select = $solarium->createSelect(); // configure dismax $dismax = $select->getDisMax(); $dismax->setQueryFields(array('name^4', 'description', 'tags', 'text', 'text_ngram', 'name_split^2')); $dismax->setPhraseFields(array('description')); $dismax->setBoostFunctions(array('log(trendiness)^10')); $dismax->setMinimumMatch(1); $dismax->setQueryParser('edismax'); // filter by type if ($typeFilter) { $filterQueryTerm = sprintf('type:"%s"', $select->getHelper()->escapeTerm($typeFilter)); $filterQuery = $select->createFilterQuery('type')->setQuery($filterQueryTerm); $select->addFilterQuery($filterQuery); } if ($req->query->has('search_query')) { $form->bind($req); if ($form->isValid()) { $escapedQuery = $select->getHelper()->escapeTerm($form->getData()->getQuery()); $escapedQuery = preg_replace('/(^| )-(S)/', '$1-$2', $escapedQuery); $escapedQuery = preg_replace('/(^| )+(S)/', '$1+$2', $escapedQuery); if ((substr_count($escapedQuery, '"') % 2) == 0) { $escapedQuery = str_replace('"', '"', $escapedQuery); } $select->setQuery($escapedQuery); } } $paginator = new Pagerfanta(new SolariumAdapter($solarium, $select)); $perPage = $req->query->getInt('per_page', 15); if ($perPage <= 0 || $perPage > 100) { if ($req->getRequestFormat() === 'json') { return JsonResponse::create(array( 'status' => 'error', 'message' => 'The optional packages per_page parameter must be an integer between 1 and 100 (default: 15)', ), 400)->setCallback($req->query->get('callback')); } $perPage = max(0, min(100, $perPage)); } } elseif ($req->getRequestFormat() === 'json') { return JsonResponse::create(array( 'error' => 'Missing search query, example: ?q=example' ), 400)->setCallback($req->query->get('callback')); } return $this->render('SomeAppWebBundle:Web:search.html.twig'); }
  • 28. { $form = $this->createForm(new SearchQueryType, new SearchQuery); $filteredOrderBys = $this->getFilteredOrderedBys($req); $normalizedOrderBys = $this->getNormalizedOrderBys($filteredOrderBys); $this->computeSearchQuery($req, $filteredOrderBys); $typeFilter = $req->query->get('type'); $tagsFilter = $req->query->get('tags'); if ($req->query->has('search_query') || $typeFilter || $tagsFilter) { /** @var $solarium Solarium_Client */ $solarium = $this->get('solarium.client'); $select = $solarium->createSelect(); // configure dismax $dismax = $select->getDisMax(); $dismax->setQueryFields(array('name^4', 'description', 'tags', 'text', 'text_ngram', 'name_split^2')); $dismax->setPhraseFields(array('description')); $dismax->setBoostFunctions(array('log(trendiness)^10')); $dismax->setMinimumMatch(1); $dismax->setQueryParser('edismax'); // filter by type if ($typeFilter) { $filterQueryTerm = sprintf('type:"%s"', $select->getHelper()->escapeTerm($typeFilter)); $filterQuery = $select->createFilterQuery('type')->setQuery($filterQueryTerm); $select->addFilterQuery($filterQuery); } // filter by tags if ($tagsFilter) { $tags = array(); foreach ((array) $tagsFilter as $tag) { $tags[] = $select->getHelper()->escapeTerm($tag); } $filterQueryTerm = sprintf('tags:("%s")', implode('" AND "', $tags)); $filterQuery = $select->createFilterQuery('tags')->setQuery($filterQueryTerm); $select->addFilterQuery($filterQuery); } if (!empty($filteredOrderBys)) { $select->addSorts($normalizedOrderBys); } if ($req->query->has('search_query')) { $form->bind($req); if ($form->isValid()) { $escapedQuery = $select->getHelper()->escapeTerm($form->getData()->getQuery()); $escapedQuery = preg_replace('/(^| )-(S)/', '$1-$2', $escapedQuery); $escapedQuery = preg_replace('/(^| )+(S)/', '$1+$2', $escapedQuery); if ((substr_count($escapedQuery, '"') % 2) == 0) { $escapedQuery = str_replace('"', '"', $escapedQuery); } $select->setQuery($escapedQuery); } } $paginator = new Pagerfanta(new SolariumAdapter($solarium, $select)); $perPage = $req->query->getInt('per_page', 15); if ($perPage <= 0 || $perPage > 100) { if ($req->getRequestFormat() === 'json') { return JsonResponse::create(array( 'status' => 'error', 'message' => 'The optional packages per_page parameter must be an integer between 1 and 100 (default: 15)', ), 400)->setCallback($req->query->get('callback')); } $perPage = max(0, min(100, $perPage)); } $paginator->setMaxPerPage($perPage); $paginator->setCurrentPage($req->query->get('page', 1), false, true); $metadata = array(); foreach ($paginator as $package) { if (is_numeric($package->id)) { $metadata['downloads'][$package->id] = $package->downloads; $metadata['favers'][$package->id] = $package->favers; } } if ($req->getRequestFormat() === 'json') { try { $result = array( 'results' => array(), 'total' => $paginator->getNbResults(), ); } catch (Solarium_Client_HttpException $e) { return JsonResponse::create(array( 'status' => 'error', 'message' => 'Could not connect to the search server', ), 500)->setCallback($req->query->get('callback')); } return JsonResponse::create($result)->setCallback($req->query->get('callback')); } if ($req->isXmlHttpRequest()) { try { return $this->render('PackagistWebBundle:Web:search.html.twig', array( 'packages' => $paginator, 'meta' => $metadata, 'noLayout' => true, )); } catch (Twig_Error_Runtime $e) { if (!$e->getPrevious() instanceof Solarium_Client_HttpException) { throw $e; } return JsonResponse::create(array( 'status' => 'error', 'message' => 'Could not connect to the search server', ), 500)->setCallback($req->query->get('callback')); } } return $this->render('PackagistWebBundle:Web:search.html.twig', array( 'packages' => $paginator, 'meta' => $metadata, )); } elseif ($req->getRequestFormat() === 'json') { return JsonResponse::create(array( 'error' => 'Missing search query, example: ?q=example' ), 400)->setCallback($req->query->get('callback')); } return $this->render('PackagistWebBundle:Web:search.html.twig');
  • 29. { $form = $this->createForm(new SearchQueryType, new SearchQuery); $filteredOrderBys = $this->getFilteredOrderedBys($req); $normalizedOrderBys = $this->getNormalizedOrderBys($filteredOrderBys); $this->computeSearchQuery($req, $filteredOrderBys); $typeFilter = $req->query->get('type'); $tagsFilter = $req->query->get('tags'); if ($req->query->has('search_query') || $typeFilter || $tagsFilter) { /** @var $solarium Solarium_Client */ $solarium = $this->get('solarium.client'); $select = $solarium->createSelect(); // configure dismax $dismax = $select->getDisMax(); $dismax->setQueryFields(array('name^4', 'description', 'tags', 'text', 'text_ngram', 'name_split^2')); $dismax->setPhraseFields(array('description')); $dismax->setBoostFunctions(array('log(trendiness)^10')); $dismax->setMinimumMatch(1); $dismax->setQueryParser('edismax'); // filter by type if ($typeFilter) { $filterQueryTerm = sprintf('type:"%s"', $select->getHelper()->escapeTerm($typeFilter)); $filterQuery = $select->createFilterQuery('type')->setQuery($filterQueryTerm); $select->addFilterQuery($filterQuery); } // filter by tags if ($tagsFilter) { $tags = array(); foreach ((array) $tagsFilter as $tag) { $tags[] = $select->getHelper()->escapeTerm($tag); } $filterQueryTerm = sprintf('tags:("%s")', implode('" AND "', $tags)); $filterQuery = $select->createFilterQuery('tags')->setQuery($filterQueryTerm); $select->addFilterQuery($filterQuery); } if (!empty($filteredOrderBys)) { $select->addSorts($normalizedOrderBys); } if ($req->query->has('search_query')) { $form->bind($req); if ($form->isValid()) { $escapedQuery = $select->getHelper()->escapeTerm($form->getData()->getQuery()); $escapedQuery = preg_replace('/(^| )-(S)/', '$1-$2', $escapedQuery); $escapedQuery = preg_replace('/(^| )+(S)/', '$1+$2', $escapedQuery); if ((substr_count($escapedQuery, '"') % 2) == 0) { $escapedQuery = str_replace('"', '"', $escapedQuery); } $select->setQuery($escapedQuery); } } $paginator = new Pagerfanta(new SolariumAdapter($solarium, $select)); $perPage = $req->query->getInt('per_page', 15); if ($perPage <= 0 || $perPage > 100) { if ($req->getRequestFormat() === 'json') { return JsonResponse::create(array( 'status' => 'error', 'message' => 'The optional packages per_page parameter must be an integer between 1 and 100 (default: 15)', ), 400)->setCallback($req->query->get('callback')); } $perPage = max(0, min(100, $perPage)); } $paginator->setMaxPerPage($perPage); $paginator->setCurrentPage($req->query->get('page', 1), false, true); $metadata = array(); foreach ($paginator as $package) { if (is_numeric($package->id)) { $metadata['downloads'][$package->id] = $package->downloads; $metadata['favers'][$package->id] = $package->favers; } } if ($req->getRequestFormat() === 'json') { try { $result = array( 'results' => array(), 'total' => $paginator->getNbResults(), ); } catch (Solarium_Client_HttpException $e) { return JsonResponse::create(array( 'status' => 'error', 'message' => 'Could not connect to the search server', ), 500)->setCallback($req->query->get('callback')); } return JsonResponse::create($result)->setCallback($req->query->get('callback')); } if ($req->isXmlHttpRequest()) { try { return $this->render('PackagistWebBundle:Web:search.html.twig', array( 'packages' => $paginator, 'meta' => $metadata, 'noLayout' => true, )); } catch (Twig_Error_Runtime $e) { if (!$e->getPrevious() instanceof Solarium_Client_HttpException) { throw $e; } return JsonResponse::create(array( 'status' => 'error', 'message' => 'Could not connect to the search server', ), 500)->setCallback($req->query->get('callback')); } } return $this->render('PackagistWebBundle:Web:search.html.twig', array( 'packages' => $paginator, 'meta' => $metadata, )); } elseif ($req->getRequestFormat() === 'json') { return JsonResponse::create(array( 'error' => 'Missing search query, example: ?q=example' ), 400)->setCallback($req->query->get('callback')); } return $this->render('PackagistWebBundle:Web:search.html.twig'); { $form = $this->createForm(new SearchQueryType, new SearchQuery); $filteredOrderBys = $this->getFilteredOrderedBys($req); $normalizedOrderBys = $this->getNormalizedOrderBys($filteredOrderBys); $this->computeSearchQuery($req, $filteredOrderBys); $typeFilter = $req->query->get('type'); $tagsFilter = $req->query->get('tags'); if ($req->query->has('search_query') || $typeFilter || $tagsFilter) { /** @var $solarium Solarium_Client */ $solarium = $this->get('solarium.client'); $select = $solarium->createSelect(); // configure dismax $dismax = $select->getDisMax(); $dismax->setQueryFields(array('name^4', 'description', 'tags', 'text', 'text_ngram', 'name_split^2')); $dismax->setPhraseFields(array('description')); $dismax->setBoostFunctions(array('log(trendiness)^10')); $dismax->setMinimumMatch(1); $dismax->setQueryParser('edismax'); // filter by type if ($typeFilter) { $filterQueryTerm = sprintf('type:"%s"', $select->getHelper()->escapeTerm($typeFilter)); $filterQuery = $select->createFilterQuery('type')->setQuery($filterQueryTerm); $select->addFilterQuery($filterQuery); } // filter by tags if ($tagsFilter) { $tags = array(); foreach ((array) $tagsFilter as $tag) { $tags[] = $select->getHelper()->escapeTerm($tag); } $filterQueryTerm = sprintf('tags:("%s")', implode('" AND "', $tags)); $filterQuery = $select->createFilterQuery('tags')->setQuery($filterQueryTerm); $select->addFilterQuery($filterQuery); } if (!empty($filteredOrderBys)) { $select->addSorts($normalizedOrderBys); } if ($req->query->has('search_query')) { $form->bind($req); if ($form->isValid()) { $escapedQuery = $select->getHelper()->escapeTerm($form->getData()->getQuery()); $escapedQuery = preg_replace('/(^| )-(S)/', '$1-$2', $escapedQuery); $escapedQuery = preg_replace('/(^| )+(S)/', '$1+$2', $escapedQuery); if ((substr_count($escapedQuery, '"') % 2) == 0) { $escapedQuery = str_replace('"', '"', $escapedQuery); } $select->setQuery($escapedQuery); } } $paginator = new Pagerfanta(new SolariumAdapter($solarium, $select)); $perPage = $req->query->getInt('per_page', 15); if ($perPage <= 0 || $perPage > 100) { if ($req->getRequestFormat() === 'json') { return JsonResponse::create(array( 'status' => 'error', 'message' => 'The optional packages per_page parameter must be an integer between 1 and 100 (default: 15)', ), 400)->setCallback($req->query->get('callback')); } $perPage = max(0, min(100, $perPage)); } $paginator->setMaxPerPage($perPage); $paginator->setCurrentPage($req->query->get('page', 1), false, true); $metadata = array(); foreach ($paginator as $package) { if (is_numeric($package->id)) { $metadata['downloads'][$package->id] = $package->downloads; $metadata['favers'][$package->id] = $package->favers; } } if ($req->getRequestFormat() === 'json') { try { $result = array( 'results' => array(), 'total' => $paginator->getNbResults(), ); } catch (Solarium_Client_HttpException $e) { return JsonResponse::create(array( 'status' => 'error', 'message' => 'Could not connect to the search server', ), 500)->setCallback($req->query->get('callback')); } return JsonResponse::create($result)->setCallback($req->query->get('callback')); } if ($req->isXmlHttpRequest()) { try { return $this->render('PackagistWebBundle:Web:search.html.twig', array( 'packages' => $paginator, 'meta' => $metadata, 'noLayout' => true, )); } catch (Twig_Error_Runtime $e) { if (!$e->getPrevious() instanceof Solarium_Client_HttpException) { throw $e; } return JsonResponse::create(array( 'status' => 'error', 'message' => 'Could not connect to the search server', ), 500)->setCallback($req->query->get('callback')); } } return $this->render('PackagistWebBundle:Web:search.html.twig', array( 'packages' => $paginator, 'meta' => $metadata, )); } elseif ($req->getRequestFormat() === 'json') { return JsonResponse::create(array( 'error' => 'Missing search query, example: ?q=example' ), 400)->setCallback($req->query->get('callback')); } return $this->render('PackagistWebBundle:Web:search.html.twig');
  • 31. Creation → Change Project Lifetime Beginning 3 months 6 months 9 months ... Cost of Creation Cost of Change
  • 32. Creation → Change Project Lifetime Beginning 3 months 6 months 9 months ... Cost of Creation Cost of Change Enterprise Project
  • 33. Creation → Change Project Lifetime Beginning 3 months 6 months 9 months ... Cost of Creation Cost of Change Enterprise Project Enterprise Project
  • 42. Delegated Code The framework / library code Controlled Code
  • 47. Owned Code Delegated Code Change Controlled Code
  • 48. Owned Code Delegated Code Change Controlled Code
  • 49. Owned Code Delegated Code Change Controlled Code
  • 50. Owned Code Delegated Code Controlled Code
  • 52. – An engineer “Ah, to hell with that!”
  • 65. – A business person “Why does it always take so long?”
  • 72. Project Lifetime Beginning 3 months 6 months 9 months ... Cost of Creation Cost of Change Cost of Control
  • 73. CONTROL IS A LIMITER FOR A COST OF CHANGE
  • 74. Project Lifetime Beginning 3 months 6 months 9 months ... Cost of Creation Cost of Change Cost of Control
  • 76. Project Lifetime Beginning 3 months 6 months 9 months ... Cost of Creation Cost of Change Cost of Control
  • 78. Project Lifetime Beginning 3 months 6 months 9 months ... Cost of Creation Cost of Change Cost of Control
  • 82. 4 RULES OF MIN-MAXING 1. Begin from owning nothing ( ) 2. Take ownership reluctantly ( ) 3. Control everything you own ( ) 4. Continuously reassess your control ( )
  • 83. HEALTHY YOUNG PROJECT Owned Code Delegated Code Controlled Code
  • 84. UNHEALTHY YOUNG PROJECT Owned Code Delegated Code Controlled Code
  • 85. UNHEALTHY YOUNG PROJECT Owned Code Delegated Code Controlled Code
  • 86. HEALTHY MATURE PROJECT Owned Code Delegated Code Controlled Code
  • 87. UNHEALTHY “MATURE” PROJECT Owned Code Delegated Code Controlled Code
  • 88. UNHEALTHY “MATURE” PROJECT Owned Code Delegated Code Controlled Code
  • 93. Project Lifetime Beginning 3 months 6 months 9 months ... Cost of Creation Cost of Change Cost of Control
  • 94. Control everything you write. Avoid writing anything.