min-maxing software costs
TRANSCRIPT
![Page 1: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/1.jpg)
MIN-MAXINGSoftware Costs
Konstantin K.@everzet
![Page 2: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/2.jpg)
TECHNICALDEBT
![Page 3: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/3.jpg)
Without frameworks
Simple frameworks
Enterprise frameworks
![Page 4: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/4.jpg)
IS MESSPART OF
A COURSE?
![Page 5: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/5.jpg)
MIN-MAXING SOFTWARE COSTS
![Page 6: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/6.jpg)
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
![Page 7: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/7.jpg)
SOFTWARE COSTS
1. Cost of Creation
2. Cost of Change
3. Cost of Control
![Page 8: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/8.jpg)
COST OF CREATION
![Page 9: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/9.jpg)
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation
![Page 10: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/10.jpg)
CONVENTIONS OPTIMISE
FOR CREATION
![Page 11: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/11.jpg)
$ bin/rails generate controller welcome index
![Page 12: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/12.jpg)
from django.contrib import admin
from . import models
admin.site.register(models.Article)
![Page 13: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/13.jpg)
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 { ... }
![Page 14: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/14.jpg)
CREATIONIS LIMITED BYTHE LIFE SPAN
![Page 15: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/15.jpg)
Creation→ Change
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation
![Page 16: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/16.jpg)
Creation→ Change
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation
Pure observation &personal experience
![Page 17: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/17.jpg)
Creation→ Change
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation
Conventional Project
![Page 18: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/18.jpg)
Creation→ Change
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation
Conventional Project
Conventional Project
![Page 19: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/19.jpg)
Convention-based projects either die a hero or live long enough to see themselves become the villain.
![Page 20: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/20.jpg)
COST OF CHANGE
![Page 21: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/21.jpg)
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation Cost of Change
![Page 22: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/22.jpg)
THE SEARCHFUNCTION
![Page 23: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/23.jpg)
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'); }
![Page 24: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/24.jpg)
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'); }
![Page 25: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/25.jpg)
HOW LONG WOULDIT TAKE TO ADD TAGS
SUPPORT?
![Page 26: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/26.jpg)
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'); }
![Page 27: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/27.jpg)
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'); }
![Page 28: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/28.jpg)
{ $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'); }
![Page 29: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/29.jpg)
{ $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'); }
![Page 30: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/30.jpg)
CHANGE KICKS IN AFTER
CREATION STOPS
![Page 31: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/31.jpg)
Creation→ Change
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation Cost of Change
![Page 32: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/32.jpg)
Creation→ Change
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation Cost of Change
Enterprise Project
![Page 33: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/33.jpg)
Creation→ Change
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation Cost of Change
Enterprise Project
Enterprise Project
![Page 34: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/34.jpg)
FORCE DYNAMICS
![Page 35: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/35.jpg)
CONVENTION-BASED FRAMEWORK
![Page 36: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/36.jpg)
![Page 37: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/37.jpg)
Your first feature
Controlled Code
![Page 38: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/38.jpg)
Controlled Code
![Page 39: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/39.jpg)
Your second feature
Controlled Code
![Page 40: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/40.jpg)
Controlled Code
![Page 41: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/41.jpg)
Controlled Code
![Page 42: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/42.jpg)
Delegated Code
The framework / library code
Controlled Code
![Page 43: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/43.jpg)
Delegated Code Controlled Code
![Page 44: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/44.jpg)
Delegated Code
Change
Controlled Code
![Page 45: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/45.jpg)
Delegated Code
Change
Controlled Code
![Page 46: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/46.jpg)
Delegated Code
Change
Controlled Code
![Page 47: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/47.jpg)
Owned Code Delegated Code
Change
Controlled Code
![Page 48: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/48.jpg)
Owned Code Delegated Code
Change
Controlled Code
![Page 49: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/49.jpg)
Owned Code Delegated Code
Change
Controlled Code
![Page 50: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/50.jpg)
Owned Code Delegated Code Controlled Code
![Page 51: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/51.jpg)
Owned Code Controlled Code
![Page 52: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/52.jpg)
– An engineer
“Ah, to hell with that!”
![Page 53: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/53.jpg)
Owned Code
![Page 54: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/54.jpg)
Owned Code
Change
![Page 55: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/55.jpg)
Owned Code
![Page 56: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/56.jpg)
ENTERPRISE FRAMEWORK
![Page 57: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/57.jpg)
![Page 58: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/58.jpg)
Controlled Code
Your first feature
![Page 59: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/59.jpg)
Controlled Code
![Page 60: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/60.jpg)
Controlled Code
Your second feature
![Page 61: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/61.jpg)
Controlled Code
![Page 62: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/62.jpg)
Controlled Code
Change
![Page 63: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/63.jpg)
Controlled Code
Change
![Page 64: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/64.jpg)
Controlled Code
Change
![Page 65: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/65.jpg)
– A business person
“Why does it always take so long?”
![Page 66: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/66.jpg)
Controlled CodeOwned Code
Change
![Page 67: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/67.jpg)
Controlled CodeOwned Code
Change
![Page 68: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/68.jpg)
Controlled CodeOwned Code
Change
![Page 69: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/69.jpg)
Controlled CodeOwned Code
![Page 70: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/70.jpg)
Owned Code
![Page 71: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/71.jpg)
CONTROL HAS COST
![Page 72: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/72.jpg)
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation Cost of Change Cost of Control
![Page 73: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/73.jpg)
CONTROL IS A LIMITER FOR ACOST OF CHANGE
![Page 74: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/74.jpg)
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation Cost of Change Cost of Control
![Page 75: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/75.jpg)
CONTROLLINGTOO FEW TOO LATE
![Page 76: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/76.jpg)
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation Cost of Change Cost of Control
![Page 77: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/77.jpg)
CONTROLLINGTOO MUCH TOO EARLY
![Page 78: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/78.jpg)
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation Cost of Change Cost of Control
![Page 79: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/79.jpg)
OWNING MORE THAN YOU CONTROLIS UNSUSTAINABLE
![Page 80: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/80.jpg)
CONTROLLING EVERYTHING
IS EXPENSIVE
![Page 81: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/81.jpg)
MIN-MAXING SOFTWARE COSTS
![Page 82: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/82.jpg)
4 RULES OF MIN-MAXING
1. Begin from owning nothing ( )
2. Take ownership reluctantly ( )
3. Control everything you own ( )
4. Continuously reassess your control ( )
![Page 83: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/83.jpg)
HEALTHY YOUNG PROJECT
Owned Code Delegated Code Controlled Code
![Page 84: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/84.jpg)
UNHEALTHY YOUNG PROJECT
Owned Code Delegated Code Controlled Code
![Page 85: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/85.jpg)
UNHEALTHY YOUNG PROJECT
Owned Code Delegated Code Controlled Code
![Page 86: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/86.jpg)
HEALTHY MATURE PROJECT
Owned Code Delegated Code Controlled Code
![Page 87: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/87.jpg)
UNHEALTHY “MATURE” PROJECT
Owned Code Delegated Code Controlled Code
![Page 88: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/88.jpg)
UNHEALTHY “MATURE” PROJECT
Owned Code Delegated Code Controlled Code
![Page 89: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/89.jpg)
1. BEGINFROM OWNING
NOTHING
![Page 90: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/90.jpg)
2. TAKEOWNERSHIP
RELUCTANTLY
![Page 91: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/91.jpg)
3. CONTROLEVERYTHINGYOU OWN
![Page 92: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/92.jpg)
4. CONTINUOUSLYREASSESS YOUR
CONTROL
![Page 93: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/93.jpg)
Project Lifetime
Beginning 3 months 6 months 9 months ...
Cost of Creation Cost of Change Cost of Control
![Page 94: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/94.jpg)
Control everything you write.Avoid writing anything.
![Page 95: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/95.jpg)
Deliver business impact,not software.
![Page 96: Min-Maxing Software Costs](https://reader031.vdocuments.mx/reader031/viewer/2022022414/5870df851a28abcf288b466b/html5/thumbnails/96.jpg)
THANK YOU FOR YOUR TIME!
Konstantin K.@everzet