I've been working on a project and I decided it'd be a good idea to have some sort of, like, DAO, but simplified.
Basically, the only thing I want from it (right now, at least) is to fetch me objects by model name and id. I wrote this very simple piece of code:
class DAO {
public static function get($className,$id) {
$queryName = $className."Query";
if (!class_exists($className) || !class_exists($queryName)) {
return false;
}
$q = $queryName::create()->filterByID($id)->find();
return $q;
}
}
However, I found myself stuck with the implementation. I guess I need to somehow autoload it so that it'll be able to check for the existence of the classes and so that I could use it anywhere inside my app, but I don't know how. Can anyone help me out? Or if there's a better way to do that, I'll appreciate any input.
What you're looking for is a Service.
Definition from the documentation:
Put simply, a Service is any PHP object that performs some sort of
"global" task. It's a purposefully-generic name used in computer
science to describe an object that's created for a specific purpose
(e.g. delivering emails). Each service is used throughout your
application whenever you need the specific functionality it provides.
Defining your class as a service is as simple as this:
app/config/config.yml
...
services:
my_dao:
class: Your\Bundle\DAO
...
Now you can access DAO in your controllers doing something like this:
$dao = $this->get('my_dao');
When you make this call, the Service Container will create an instance of your class and return it. There will always be at most one instance (singleton) and if it's never called, it won't even be instantiated.
I recommend reading the documentation.
Opinion
It seems like you're having trouble adapting to the Symfony way.
If you take a look at The Book you'll see that the Entity Manager in conjunction with your entity's Repository handle most of what DAO's traditionally did. In other words, there's really no need for your DAO class.
For example, fetching any object by id is as easy as:
$om->getRepository('YourBundle:YourModel')->find($id);
Anyway, if you're particularly fond of that approach, you may want to try this project.
Related
I have a bone to pick with dependency injection. It seems like such a simple concept has led to a lot of confusion amongst many, and the 'right' way to it seems to spiral out of control in terms of complexity. In keeping things really simple I just want to know:
Is it good practice if I use standard functions to register my dependencies, like this:
function someObject() {
return new someObject();
}
And can I pass parameters?
function someObject($param1) {
return new someObject($param1);
}
Finally how about using a simple custom container class:
class Dependencies {
function someObject($param1) {
return new someObject($param1);
}
}
And using it:
class SomeClass {
public function __construct(Dependencies $dependencies) {
$this->dependencies = $dependencies
}
public function methodNeedsDependency() {
$param1 = 'one';
$task = $this->dependencies->someObject($param1);
}
}
I guess what I'm asking is, is this a decent attempt at a very simple implementation of a DIC? Or are there some underlying major issues bubbling under the surface?
Thanks!
If SomeClass is a factory, designed to create some instance with some exact config given, then yes, we could say this is very simple implementation of DIC.
Issues here? Well, let's say You want to create someObject with other constructor params.
Solutions:
Create another SomeClass factory that will pass other params. It's redundant solution that also mixes two application layers ( config with object creation layer ).
Parametrize methodNeedsDependency with params that will be passed to someObject. It's something that allows You to postpone in code config creation.
and last but the most proper way: DIC should be flexible, should allow You to create any service instances with any dependencies, and all of configuration should be stored in configuration layer. Separation of concerns - try to make DIC unaware of what object type is creating. Just let him make objects that You described somewhere else.
There are a lot of other issues also, like for example what if You would like to have only one instance of given class for whole DIC ( it's easy to "if" it, but that's another workaround to proper solution ) or what with circular references.
This discussion can go on and on with other issues about architecture in general, like "services should be stateless" what makes it unnecesary to have more then one, but answer to your question are those 3 points. Of course remember it's not ultimate-mega-hiper answer for DIC. It's just my way of seeing it ;-)
Background: I'm working on an MVC framework for some practice, and want to make sure everything is 100% unit tested.
The setup currently is to have an instance of the application class (Ex_App). The main script asks a Dispatcher/Router for a controller name. This controller name is the name of a class implementing Ex_Controller. The result is returned as an instance of Ex_Dispatch_Result. This result is passed to the Ex_App instance using an invokeController($dispatchResult) function.
And this is where magic happens. The listing below is an excerpt:
$controllerName = $dispatchResult->getControllerName();
... checks for validaty of class name ...
$controller = new $controllerName();
$controller->prepare($this);
I'm using PHPUnit to do my unit testing, and am able to mock the dispatch result, correctly check that validating the class name of the controller works. The problem is how to check if prepare is called.
I'd like to do something similar to:
$mockController = $this->getMockBuilder('Ex_Controller')
->setMockClassName('Invoke_Correct_Controller')
->getMock();
$mockController->expects($this->once())->method('prepare');
However since a new instance of Invoke_Correct_Controller is created upon calling invokeController, it will not be this mock and thus the expects() call is completely irrelevant.
I could make the Ex_Dispatch_Result class responsible for returning a controller and testing that, but before returning an instance I will need to verify the correctness of the class name and in my opinion that responsibility should be with the Ex_App class and not the "dumb shell" Ex_Dispatch_Result class.
Is there something I am missing in the PHPUnit framework that I could use to test the code here, or some useful pattern that could work in my instance? I feel passing around controller names scales way better than passing around instances of controllers from the start, requiring the initialization of every possible controller. So, I kinda want to stick to passing around names and using the Ex_App as a factory for the controller instance.
Maybe I'm just over-thinking part of this problem, but that happens sometimes. It's why a fresh look by a third party often works :-)
There are couple of things you could do:
Extract controller creation logic to separate class e.g. ControllerFactory, and then mock controller factory instance, so that it returns your $mockController.
Extract controller creation logic to separate method and use partial mocking.
Return $mockController from $dispatchResult->getControllerName(), which probably requires mocking of $dispatchResult or even something else.
If you want more detailed answer, please provide more code samples of your classes and methods.
First of all, sorry for my bad English, I hope you understand what I'm saying.
Here is my problem:
Lets assume i have an MVC application including standard router, controller, model(service) layer and some kind of db connector.
Model layer depends on a db connector, controllers depends on models/services and the top-level "application" class depends on routers and controllers.
My object hierarchy looks like this:
App -> ControllerFactory -> ServiceFactory -> DAO -> DbConnection
Perhaps, written above doesn't look like best application architecture ever, but i want to focus on the other thing:
When i'm trying to instantiate an App class i should pass all dependencies to the class instantiated; class dependencies, in turn, has their own dependencies and so on.
As a result I get all hierarchy stack instantiated at once. But what if i dont need to access the database in some cases; what if some controllers are used for rendering static templates without model interaction?
I mean, what if there are some special cases when class does not require its own dependencies(and in some cases it does)? Should i inject dependencies conditionaly or something?
I'm really stuck at this point and i don't know what to do.
Update: after re-reading carefully your question, here is another advice: yes, every class has different dependencies.
Don't inject every object into every other object. For example, some services might need DAOs, so inject them. But if a service doesn't need a DAO, don't inject any DAO.
The rest of my answer is valid if you have (for example) a service that needs a DAO (and thus a DB connection) not for every method.
What you may be looking for is lazy injection.
It is the act of injecting a dependency not loaded, so that the object is loaded only if/when used.
In conrete terms, that means injecting a proxy object, that would look like and behave exactly like the original object (for example, the db connection).
Several DI container (frameworks) support this so you don't have to create proxies yourself. I'll take as an example PHP-DI (I work on that project FYI).
Here is an example using annotations:
use DI\Annotation\Inject;
class Example {
/**
* #Inject(lazy=true)
* #var My\Class
*/
protected $property;
/**
* #Inject({ "param1" = {"lazy"=true} })
*/
public function method(My\Class $param1) {
}
}
Of course if you don't want to use annotations you can use any other configuration you want (PHP, YAML, …). Here is the same example by configuring the container in pure PHP:
$container->set('Example')
->withProperty('property', 'My\Class', true)
->withMethod('method', array('param1' => array(
'name' => 'My\Class',
'lazy' => true,
)));
See more in the documentation about Lazy Injection.
Note: you may not be using a Container for now (and that's not a problem), but for tackling lazy injection this is a fair amount of work and you might need to start considering using one.
If your dependency construction is complex, simply add a new factory class that should contain all the logic to create a correct object for you.
class AppFactory(){
__construct(all params){
}
build(useDB=true){
// logic to build
if(useDB){
App = new App(new ControllerFactory(new ServiceFactory(new DAO(new DbConnection(params)))))
} else {
App = new App(new ControllerFactory(new ServiceFactory(null))))
}
return App;
}
}
My code is located here: https://github.com/maniator/SmallFry
Should I make it so that that the App class does not have to use static functions but at the same time be able to set and set variables for the app from anywhere?
Or should I keep it how it is now with App::get and App::set methods?
What are the advantages and disadvantages of both?
How would I accomplish that 1st task if I was to undertake it?
Related Question
Sample code:
//DEFAULT TEMPLATE
App::set('APP_NAME', 'SmallVC');
//END DEFAULT TEMPLAT
//
//DEFAULT TEMPLATE
App::set('DEFAULT_TEMPLATE', 'default');
//END DEFAULT TEMPLATE
//DEFAULT TITLE
App::set('DEFAULT_TITLE', 'Small-VC');
//END DEFAULT TITLE
//LOGIN SEED
App::set('LOGIN_SEED', "lijfg98u5;jfd7hyf");
//END LOGIN SEED
App::set('DEFAULT_CONTROLLER', 'AppController');
if(App::get('view')){
$template_file = $cwd.'/../view/'.App::get('view').'/'.App::get('method').'.stp';
if(is_file($template_file)){
include $template_file;
}
else {
include $cwd.'/../view/missingview.stp'; //no such view error
}
}
else {
App::set('template', 'blank');
include $cwd.'/../view/missingfunction.stp'; //no such function error
}
I think you have a feeling that static is bad. What I am posting may seem fairly crazy as it is a massive change. At the very least hopefully it presents a different idea of the world.
Miško Hevery wrote static methods are a death to testability.
I like testing, so for that reason I don't use them. So, how else can we solve the problem? I like to solve it using what I think is a type of dependency injection. Martin Fowler has a good but complicated article on it here.
For each object at construction I pass the objects that are required for them to operate. From your code I would make AppController become:
class AppController
{
protected $setup;
public function __construct(array $setup = array())
{
$setup += array('App' => NULL, 'Database' => NULL);
if (!$setup['App'] instanceof App)
{
if (NULL !== $setup['App'])
{
throw new InvalidArgumentException('Not an App.');
}
$setup['App'] = new App();
}
// Same for Database.
// Avoid doing any more in the constructor if possible.
$this->setup = $setup;
}
public function otherFunction()
{
echo $this->setup['App']->get('view');
}
}
The dependancies default to values that are most likely (your default constructions in the if statements). So, normally you don't need to pass a setup. However, when you are testing or want different functionality you can pass in mocks or different classes (that derive from the right base class). You can use interfaces as an option too.
Edit The more pure form of dependency injection involves further change. It requires that you pass always pass required objects rather than letting the class default one when the object isn't passed. I have been through a similar change in my codebase of +20K LOC. Having implemented it, I see many benefits to going the whole way. Objects encapsulation is greatly improved. It makes you feel like you have real objects rather than every bit of code relying on something else.
Throwing exceptions when you don't inject all of the dependencies causes you to fix things quickly. With a good system wide exception handler set with set_exception_handler in some bootstrap code you will easily see your exceptions and can fix each one quickly. The code then becomes simpler in the AppController with the check in the constructor becoming:
if (!$setup['App'] instanceof App)
{
throw new InvalidArgumentException('Not an App.');
}
With every class you then write all objects would be constructed upon initialisation. Also, with each construction of an object you would pass down the dependencies that are required (or let the default ones you provide) be instantiated. (You will notice when you forget to do this because you will have to rewrite your code to take out dependencies before you can test it.)
It seems like a lot of work, but the classes reflect the real world closer and testing becomes a breeze. You can also see the dependencies you have in your code easily in the constructor.
Well, if it was me, I would have the end goal of injecting the App dependency into any class (or class tree) that needs it. That way in testing or reusing the code you can inject whatever you want.
Note I said reuse there. That's because it's hard to re-use code that has static calls in it. That's because it's tied to the global state so you can't really "change" the state for a subrequest (or whatever you want to do).
Now, on to the question at hand. It appears that you have a legacy codebase, which will complicate things. The way I would approach it is as follows:
Create a non-static version of the app class (name it something different for now) that does nothing but proxy its get/set calls to the real app class. So, for example:
class AppProxy {
public function set($value) {
return App::set($value);
}
}
For now, all it has to do is proxy. Once we finish getting all the code talking to the proxy instead of the static app, we'll make it actually function. But until then, this will keep the application running. That way you can take your time implementing these steps and don't need to do it all in one big sweep.
Pick a main class (one that does a lot for the application, or is important) that you easily control the instantiation of. Preferably one that you instantiate in only one place (in the bootstrap is the easiest). Change that class to use Dependency Injection via the constructor to get the "appproxy".
a. Test this!
Pick another class tree to work on, based on what you think will be most important and easiest.
a. Test!!!
If you have more calls to App::, Go to #3
Change the existing App class to be non-static.
a. Test!!!!!!!!!!
Remove the AppProxy and replace with App in the dependency injectors. If you did it right, you should only have one place to change to make this switch.
Pat yourself on the back and go get a drink, cause you're done.
The reason that I segmented it out like this is that once a step is completed (any step), you can still ship working software. So this conversion could take literally months (depending on the size of your codebase) without interrupting business as usual...
Now, once you're done, you do get some significant benefits:
Easy to test since you can just create a new App object to inject (or mock it as needed).
Side effects are easier to see since the App object is required wherever it could be changed.
It's easier to componentize libraries this way since their side effects are localized/
It's easier to override (polymorphism) the core app class if it's injected than if it's static.
I could go on, but I think it's pretty easy to find resources on why statics are generally bad. So that's the approach I would use to migrate away from a static class to an instance...
If you don't want to have static functions but global access from everywhere WITHOUT passing the object to the places where it is actually needed then you pretty much can only use one thing:
A global variable
So you are not really better of doing that. But that is the only thing i can think of that would fulfill your requirements.
If you App object is something like an application config a first possible step would be to pass it to the objects that need it:
class Login {
public function __construct() {
$this->_login_seed = App::get('LOGIN_SEED');
self::$_ms = Database::getConnection();
}
changes into:
class Login {
public function __construct(App $app) {
$this->_login_seed = $app->get('LOGIN_SEED');
self::$_ms = Database::getConnection();
}
I'm looking for help identifying this design pattern and learning the "typical" vocabulary it uses:
I'm working on a project in PHP, and I've created a thin ORM layer that saves generic objects to and from the database. There are two classes that do the work:
"my_object" is basically a container for various kinds of data. After being created this object can save itself to the db.
"my_object_manager" is used to manage a set of objects, for instance if you wanted to retrieve many of them and iterate through them.
As a simplified example, you could do something like:
$post = new my_object('post');
$post->title = 'foo';
$post->body = 'bar';
$post->author = 'baz';
...and you if you wanted to load a bunch of posts you could do something like:
$posts = new my_object_manager('post');
$somePosts = $posts->getBy('author','baz');
foreach( $somePosts as $aPost ) {
...loop stuff here...
}
So, my question is this: In the class definition for "my_object_manager" I need to store a property that identifies what kind of object is being managed. It looks something like this:
class my_object_manager {
protected $theKindOfObjectThatThisManages;
function __construct($whatToManage) {
$this->theKindOfObjectThisManages = $whatToManage;
}
}
Now, forgive me for not knowing this kind of basic stuff, but I'm self-taught and have a pretty limited programming vocabulary. I'm sure this kind of design pattern is common, but for the life of me I haven't been able to figure out what it's called.
I'm trying to write code that other programmers can read and understand, SO, my real question is if you were reading this code what would you expect "$theKindOfObjectThatThisManages" to be called? What is this program design pattern called, and what do you call this kind of an object if you want other programmers to know what it's doing?
Lastly, the question editor popped up and told me that this question looks subjective and is likely to be closed. I hope that this question is, in fact, ok for Stack Overflow - but if not, where could I ask this question and get an answer?
Thank you!
For your code samples, I would use
class my_object_manager {
protected $my_object_type;
function __construct($whatToManage) {
$this->my_object_type = $whatToManage;
}
}
Now, you seem to be following closely the Active Record pattern, of which many implementations exist, you can go see how they do it in practice :)
Usually, you don't provide access to _manager() objects, but make my_object()s inherit from it. So, you'd have something like
$posts = new Posts(); //Where Posts() extends my_object_manager
$somePosts = $posts->getBy('author','baz');
foreach( $somePosts as $aPost ) {
...loop stuff here...
}
Check out:
http://en.wikipedia.org/wiki/Design_pattern_(computer_science)
Your object manager's design, depending on how complex it gets, may fall under several patterns. For example:
Composite: Maybe your object manager allows you to run updates on multiple objects at once (typical database scenario) using the same interface. You can alter individual objects in the same way you'd alter collections.
Facade: If your object manager provides methods to combine various parts of your system into a single, easier to use interface then it's using the Facade pattern. For example, maybe your object manager creates a 'user' object and automatically generates their first 'post' via a single API call. Perhaps you could have used create() functions on the post and user objects to do this yourself, but the Facade pattern combines them (and perhaps helps to deal with concurrency issues as well) into an easier API since these operations are commonly called together.
Mediator/Observer: Your object manager might be responsible for observing changes to objects and handling the "mediation" between them. Your object manager might provide a method for commenting on a post. But when this method is called, the author of the post might need to be notified via email. So your object manager could be responsible for communicating between the relevant objects and notifying a listening email service by sending an event or similar message.