All Comments
TopTalkedBooks posted at August 19, 2017
Agile Software Development, Principles, Patterns, and Practices - by Uncle Bob Martin

One of the most influential programming books I've ever read. The code is in Java, but it's east to follow even for a non-Java developer, and the truths are universal. Learn the most fundamental design and encapsulation patterns. Uncle Bob Martin is a legend. This book has probably made me tens of thousands of dollars.

https://www.amazon.com/Software-Development-Principles-Patte...

TopTalkedBooks posted at August 20, 2017

Loosely coupling is beneficial in all circumstances, but you should also be aware of the additional complexity it may introduce. If you apply the Dependency Inversion principle (read Robert C. Martin's book on Agile Principles for an excellent discussion), you might consider the File.IO library to define an abstraction (e.g. an interface) that it needs for logging. You can then provide an implementation of that abstraction using your preferred logging library. To be clear, that's not the same as using the abstraction offered by the logging library in the File.IO library. Then you would still be locking them together.

TopTalkedBooks posted at August 20, 2017

I liked these books:

You should also read code. If the code is hard to read, ask yourself what exactly the author did or didn't do that makes it hard to understand, and more importantly, how you can use what you've learned to write better code yourself.

TopTalkedBooks posted at August 20, 2017

Pro Spring is a superb introduction to the world of Inversion of Control and Dependency Injection. If you're not aware of these practices and their implications - the balance of topics and technical detail in Pro Spring is excellent. It builds a great case and consequent personal foundation.

Another book I'd suggest would be Robert Martin's Agile Software Development (ASD). Code smells, agile techniques, test driven dev, principles ... a well-written balance of many different programming facets.

More traditional classics would include the infamous GoF Design Patterns, Bertrand Meyer's Object Oriented Software Construction, Booch's Object Oriented Analysis and Design, Scott Meyer's "Effective C++'" series and a lesser known book I enjoyed by Gunderloy, Coder to Developer.

And while books are nice ... don't forget radio!

... let me add one more thing. If you haven't already discovered safari - take a look. It is more addictive than stack overflow :-) I've found that with my google type habits - I need the more expensive subscription so I can look at any book at any time - but I'd recommend the trial to anyone even remotely interested.

(ah yes, a little obj-C today, cocoa tomorrow, patterns? soa? what was that example in that cookbook? What did Steve say in the second edition? Should I buy this book? ... a subscription like this is great if you'd like some continuity and context to what you're googling ...)

TopTalkedBooks posted at March 18, 2018

Warning:
The information in this posts is extremely outdated. It represents my understanding of MVC pattern as it was more then 2 years ago. It will be updated when I get round to it. Probably this month (2013.09).

Damn it! (2017.11).

Model itself should not contain any SQL. Ever. It is meant to only contain domain business logic.

The approach i would recommend is to separate the responsibilities, which are not strictly "business logic" into two other other sets of constructs : Domain Objects and Data Mappers.

For example, if you are making a blog, then the Model will not be Post. Instead most likely the model will be Blog , and this model will deal with multiple Domain Objects: multiple instances of Post, Comment, User and maybe other objects.

In your model, the domain objects should not know how to store themselves in database. Or even be aware of the existence of any form of storage. That is a responsibility of Data Mappers. All you should do in the Model is to call $mapper->store( $comment );. And the data mapper should know how to store one specific type of domain objects, and win which table to put the information ( usually the storage of of single domain object actually affects multiple tables ).


Some code

(only relevant fragments from files):

  • I assume that you know how to write a good constructor .. if you have doubts, read this article
  • nothing is namespaced in example, but it should be
  • anything that begins with _ in example is protected

from /application/bootstrap.php

/* --- snip --- */

$connection = new PDO( 'sqlite::memory:' );
$model_factory = new ModelFactory( $connection );

$controller = new SomeController( $request , $model_factory );

/* --- snip --- */

$controller->{$action}();

/* --- snip --- */
  • controller does not need to be aware of database connection.
  • if you want to change DB connection for whole application, you need to change single line
  • to change the way how Model's are made, you create different class which implements same interface as ModelFactory


from /framework/classes/ModelFactory.php

/* --- snip --- */

class ModelFactory implements ModelBuilderInterface
{
   /* --- snip --- */

   protected function _prepare()
   {
      if ( $this->_object_factory === null  )
      {
         $this->_object_factory = new DomainObjectFactory;
      }
      if ( $this->_mapper_factory === null )
      {
         $this->_mapper_factory = new DataMapperFactory( $this->_connection );
      }
   }

   public function build( $name )
   {
      $this->_prepare();
      return new {$name}( $this->_object_mapper , $this->_data_mapper );
   }

   /* --- snip --- */

}
  • only data mappers will use database , only mapper factory need connection
  • all the dependencies of Model are injected in constructor
  • every DataMapper instance in the application uses same DB connection, no Global State (video) required.


file /application/controllers/SomeController.php

/* --- snip --- */

   public function get_foobar()
   {
      $factory = $this->_model_factory;
      $view = $this->_view;

      $foo = $factory->build( 'FooModel' );
      $bar = $factory->build( 'BarModel' );

      $bar->set_language( $this->_request->get('lang') );

      $view->bind( 'ergo' , $foo );

      /* --- snip --- */

   }

/* --- snip --- */
  • controller is unaware of model creation details
  • controller is only responsible for wiring and changing the state of elements


file /application/models/FooModel.php

/* --- snip --- */

   public function find_something( $param  , $filter )
   {
      $something = $this->_object_factory('FooBar');
      $mapper = $this->_mapper_factory('FooMapper');

      $something->set_type( $param );
      $mapper->use_filter( $filter )->fetch( $something );

      return $something;
   }

/* --- snip --- */
  • domain object is responsible for validating the given parameters
  • view receives and decides how to present it
  • mapper takes the object and puts in it all the required information from storage ( it doesn't have to be DB .. it could be taken from some file, or an external REST API )


I hope this will help you understand the separation between DB logic and business logic ( and actually , presentation logic too )


Few notes

Model should never extend Database or ORM, because Model is not a subset of them. By extending a class, you are declaring that has all the characteristics of the superclass, but with minor exceptions.

class Duck extends Bird{}
class ForestDuck extends Duck{}
// this is ok

class Table extends Database{}
class Person extends Table{}
// this is kinda stupid and a bit insulting

Besides the obvious logic-issues, if your Model is tightly coupled with underlaying Database, it makes the code extremely hard to test (talking about Unit Testing (video)).


I personally think, that ORMs are useless and in large project - even harmful. Problem stems from the fact that ORMs are trying to bridge two completely different ways of approaching problems : OOP and SQL.

If you start project with ORM then, after short learning curve, you are able to write simple queries very fast. But by the time you start hitting the ORM's limitations and problems, you are already completely invested in the use of ORM ( maybe even new people were hired , who were really good at your chosen , but sucked at plain SQL ). You end up in situation where every new DB related issue take more and more time to solve. And if you have been using ORM based on ActiveRecord pattern, then the problems directly influence your Models.

Uncle Bob calls this "technical debt".


Few books

loosely related to subject

Top Books
We collected top books from hacker news, stack overflow, Reddit, which are recommended by amazing people.