I am looking to just get an understanding on how you guys would implement the following.
I think I have a reasonable understanding of OOP. If I have a website and a user account can be created for this website. I understand that I can create a user class that will handle the creation of this user by passing the relevant information through to the class.
If I have to make a CuRL post to pass some information through to a third party. would it make sense to create a CuRL class for this process that the user class can instantiate, also allowing for another class to post data through as well rather than creating a static function in global space or a curl function within each class that requires this function?
Another issue I have with my understanding of OOP, is if I have many similar functions that help to perform what is required. I will tend to bunch these all into one class (utils class?). This could range from passing in an array of data to output as a select element to passing user entered data through to validate and sanitize as required and return.
I think I am just looking for clarity on what is a good implementation of code with regard to OOP. Is it OK to have floating/static functions in global space working along side classes (Can that still be considered as OOP) or should everything I code be grouped as an object within a class that it would best fit?
I hope that makes sense?
Thanks
The concept behind OOP is to structure and divide responsibilities among various classes.
Models
There are various building stones, that are normally used when you consider different aspects of your application. For instance, a User class would often be considered a Model and be tied into an ORM.
The responsibility of a Model is to map the data stored in a database to the data stored in memory by PHP (or any other language). In many cases Models can also instantiate and register themselves in the database. Which is what you're looking for. Laravel's Eloquent ORM is a good example of an ORM which supports this.
cURL helper
Depending on your own opinion and the exact use case, both of your suggestions may be useful. I myself try to divide the responsibilities of each class as much as possible, this is to reach the purpose of a divided responsibility.
So I would create a helper class which can handle communication through cURL, which you can then call from various classes. I would even take if to a further level and create a Transport interface which cURL can implement. This would allow me to easily swap cURL with another transport layer, without having to change all the objects which depends on cURL.
Concept example:
<?php
interface Transport {
const POST = 'post';
public static postRequest($url, $data);
protected static processRequest($method, $url, $data);
}
class cURL implements Transport
{
public static postRequest($url, $data) {
return self::processRequest(self::POST, $url, $data);
}
protected static processRequest($method, $url, $data) {
// Implement method
}
}
This cURL example ties well together with your third question. These are often called helper functions or helper methods. Depending on the code design your choose or the design of the framework you use, the way helper methods are called can vary.
I use Laravel which provides static methods. You can see some examples for the Hash and Auth helpers here.
OOP is not Functional programming
Global function is not a part of OOP. But there's no one to tell you whether this is good or bad practice, that is up to yourself to decide, whether this approach will work the best for your use case. Obviously it requires a certain amount of experience to consider all aspects of the chosen design patterns, but experience comes with time.
To use Laravel as an example again, they do provide some global functions that adhere to old fashioned PHP functional programming style. But the framework is mainly OO.
My suggestion to you
It sounds like you need a boilerplate for what you intend to build. I would suggest that you consider a framework to use, since frameworks will often answer the questions you're asked here. Both in terms of conventions and object responsibilities.
You could check this article for suggestions on PHP frameworks to use.
Related
Below are two ways a service layer can be implemented in an CodeIgniter application.
1st method
1.send request to the controller
2.calling service layer methods from controller
3.return processed result data set(D1) from service layer to controller
4.then according to that data set controller demand data from model
5.model return data set(D2) to the controller
6.then controller send second data set(D2) to view.
2nd method
1.send request to the controller
2.calling service layer methods from controller
3.service layer demand data from model
4.model send requested data set(d1) to the service layer
5.after some processing return generated data(d2) to controller from service layer
6.then controller send data set(d2) to view.
What is the correct way of implementing a service layer in CodeIgniter? Other than these two methods, are there any other good ways?
if you can provide an example in Code it will be great
Please note, this is not necessarily the correct way of doing it, but I'm going to explain how a framework like might typically do it and then you can learn about other methods and decide the best one for your use-case. Therefore, I do not expect this answer to be the correct one, but I hope it imparts at least a little knowledge on how things are done before someone who actually knows what they're talking about comes along and chimes in (also to those people - please feel free to edit / downvote this answer :D). Finally this also has nothing to do with CodeIgniter but frameworks in general. Your question should not only be framed as framework-agnostic, but language-agnostic also.
So I'm going to offer an opinion here and that is of the fact that all modern frameworks, specifically in PHP, do not do MVC. Why is this important? Because we all need to be speaking the same language, and 'mvc' does not exist in PHP. That's a fact. Accept that and then we can move forward onto the bastardization of the concept that frameworks use; and CodeIgnitor is a particularly great example of 'MVC' bastardization; henceforth known as "mvc" with quotes.
The plus side is that frameworks like Symfony, for example, provide an initial opinionated architecture that at least contains some form of consistency across the application, and it goes something like this:
A standard HTTP request comes in and hits the front-controller, typically app.php or app_dev.php depending on whether or not you are in development or production; one involves a lot of caching that needs to be run on each change and the other doesn't - which is perfect for development.
A router matches the current url to a controller class and an 'action' (method) within that class.
The dependency injection part of the framework figures out what objects are needed for everything from the controller forward into the model layer and back, and either instantiates or prepares to instantiate them when needed.
The controller is instantiated with any required dependencies and the relevant method is executed. This is typically where you would start your development and 'hook your code in' to the framework.
This is where you decide on your architecture, however, the most important thing from both a developer perspective and business perspective (for lower costs for future maintenance) is consistency.
I personally prefer to ensure my code is decoupled from the framework. I pass in scalars taken from the request into an application-layer service, which uses objects from the model layer (passed-in via DI) to use domain objects. The point here is that domain objects are not directly passed into the controller, they are proxied through an application-layer medium, so you can theoretically replace the entire framework surrounding this and still, all you need to do is pass those scalars into this layer before they hit the model layer and it'll all still work (think CLI calls, no more controllers).
The application-level service uses any required Repositories, Services etc (and passes those scalars into them, remember the separation?), which perform business logic, (typically these are where your design patterns come into play on a day-to-day basis), and then return that data to the application-level service.
The service then returns the data to the controller and guess what? This is where frameworks tend to fuck up! Because there is no concept of a "View" in today's frameworks. There is only a template, and you pass that data to a template and bam that's it. So in your diagram, there is absolutely no concept of a view because that's not how things are done. And to be entirely honest, I'm still using templates because they're the fastest way of doing things, but until modern frameworks get their shit together and actually start using Views, we're out of luck and have to remain steadfast when confronting the fact that some (like Laravel) refer to themselves as "mvc" frameworks.
Note, Fabien Potencier explicitly states that Symfony was not an MVC framework - at least he knows what he's talking about there. Again, this is not purist, it's important we're all speaking the same, factually correct language in computing.
So, because you like diagrams so much, here's how some might do it with today's frameworks...
This is for an application that has the concept of a Review and Criteria for each Review. And don't even get me started on Symfony forms, they're so coupled to everything they're not a serious part of any architecture.
How many effing layers do you need? We already have "MVC", in DDD we have the concept of "Application", "Domain" and "Infrastructure" seperation, so get those two working together first, then this "service layer"? Do you really need another layer, or is the above enough? Things to think about...
See, you're not stuck with the framework / http request to get the application going as a result of this separation.
See the "services" in the above diagram? They're separated from the controller so you can throw scalars from anywhere and the application will still work. I think this will give you the separation you need. It's great to do things the right way, learn how to do it, and then learn how to control yourself and be pragmatic about it when it comes to the business and it's needs, but frameworks need to sort their stuff out - and you certainly wont be writing lovely code with CodeIgniter ;)
Dependency Injection and the Adapter pattern would be a good place to start.
CodeIgniter support's neither out of the box, so you would need to write a wrapper or maybe a hook.
Your view could only support xml|html as json would need to be pre-rendered to a .json file and then returned as output but this would need to be done via code, it's easier just to return the object in that case and altered on the frontend. PHP is an embedded language which works with (xml|html)
A service model works best when it is injected(dependency injection)
into a controller/model and is listed as a property of that controller/model.
The service is then bound to an interface
For example facebook/twitter
They both have a request and response function but both follow similar patterns, yet have different endpoints.
interface SocialMediaAdapter{
public request(url);
public response();
}
public class FaceBookProvider implements SocialMediaAdapter
{
public request(url){
}
public response(){
}
}
public class TwitterProvider implements SocialMediaAdapter
{
public request(url){
}
public response(){
}
}
public class SocialMediaServiceProvider{
protected $provider = null;
public function constructor(SocialMediaAdapter $provider){
$this->provider = $provider;
}
public function fetch($url){
return $this->provider->request($url);
}
}
Dependency Injection required here
new MyController( new SocialMediaServiceProvider ( new FacebookService ) )
IMHO there is no right or wrong here:
option #1 -
If you want to re-use the service layer in multiple controllers / actions
and feed it data from different models based on the request it makes sense to go for the first one.
option 2# - However the first option could be problematic if your data model is more complicated. What if a second call to the model is needed based on the data of a first call? Using the controller for this business logic defies the whole purpose of the service layer. In this case it might be better to go for the second one.
I think the second one is the more common one.
You should use first one. Because in MVC web application, controller is used to separate your business logic from view, it's something like a gateway. You need to start processing your info using controller, from controller you should call model or service layer or anything you need & finally you should return back data to any other source from here. Your view or service layer should not directly access model.
I've been writing PHP within WordPress for a while, but I'm pretty new to straight PHP applications. I'm writing a little application that uses a few different APIs to do cross posting.
I've written the classes, but I'm not sure of the best way to have them interact.
A bit of background on the classes and their functionality. I've got a class for each API (Reddit, Imgur, Twitter), a class with some Curl helper functions, a class that carries out the process. I don't think I'll ever need more than one instance of any of these current classes. Nor will they ever need to be extended.
From what I've read, I've got a few options:
Instantiate each class as a global variable (I've heard I should avoid this)
Make the classes singletons (Also heard I maybe should avoid this)
Static methods - though some of the classes need to be instantiated and I'm not sure how that would work.
Those are the methods I've heard of. I'm expecting the answer will be none of the above. How do frameworks like Laravel do this?
This might be subjective, but I'm sure I'll learn something about patterns.
Edit: I probably should add some examples of the types of interactions required.
An API class using the CurlHelper class (I'm currently using a static method: $post_string = CurlHelper::createPostString( $post_data );)
Generating a title in one class for use when cross posting to each API
I am facing a dilemma regarding OOP design of my application. Should I make the auth class a singleton or not. I see that kohana framework and zend framework use their auth classes as a singleton. What are the disadvantages of making the authentification class a singleton? What are the pros? Also the application I am building will be an enterprise application and it needs to scale, so will my auth system also scale if it will be a singleton?
Here would be some cons:
extremely hard to test, because code is tied to name of class
introduction of global state
inability to determine causes for an effect - unrelated methods can affect each other
scattering of authentication requests all over codebase
violation of LoD
You might benefit a lot from examining, at what stage and how exactly you authenticate the user ( do not confuse with authorization ). Also, this topic might be of some interest to you.
Update:
Here are few videos you might be interested in:
Clean Code Talks: Unit Testing
Clean Code Talks: Global State and Singletons
Clean Code Talks: Don't Look For Things!
PHP UK Conference 2011: Advanced OO Patterns
Avoid using the singleton and use it only in the case when a hardware has the limitation on one object -> resource per application. If you incorporate the singleton you will unable to exchange the auth class with something else in your system you will be stacked with it. Consider that tomorrow you could receive a new requirement which say you that you need to implement the authentication using a different logic, different connection and so on. Also though about how to test your system after using the singleton how will you mock it??
Don't go for Singleton! It's no better than glorified object-oriented namespace, in fact Singleton almost just as bad as using Global variables and only slightly better than using global function libraries (which in itself is also bad). It's better to send the created object to your classes.
Since PHP 5 objects passed around to other objects are passed by reference by default. They don't create a new instance (unless using clone keyword). This allows any sort of session info to be just passed as an object to other objects that need it.
Best thing I can recommend is make a class 'Session' that carries session specific information. Send this class to your MVC objects. This allows you to test the system without Session being present (or you can create a mockup state for that purpose). While passing one object to another makes them more coupled than ideal, as long as the class is primitive enough it can be easily created in other systems or parts of the app that use the same classes.
It also makes it easier to transfer states or sessions at any given time, even within the same request.
In PHP, the object doesn't stays in the memory once the request is completed.
So even if you make your object as Singleton, every request will have its own instance of that class.
But the the difference will come when object is being accessed multiple times in a single request. In that case, singleton has following advantages:
Prevents creating multiple redundant instances, so lesser memory usage for requests.
Shares the same data across multiple accesses.
Eg: Codeigniter's get_instance function is an implementation of Singleton Concept, whereby only one Codeigniter instance is used in each request.
the situation is this.
my client (who also is a programmer) asks me to develop an address book (with mysql database) with a lot of functions. then he can interact with some class methods i provide for him. kinda like an API.
the situation is that the address book application is getting bigger and bigger, and i feel like its way better to use CodeIgniter to code it with MVC.
i wonder if i can use codeigniter, then in some way give him the access to controller methods.
eg. in a controller there are some functions u can call with the web browser.
public function create_contact($information) {..}
public function delete_contact($id) {..}
public function get_contact($id) {..}
however, these are just callable from web browser. how can i let my client have access to these functions like an API?
then in his own application he can use:
$result = $address_book->create_contact($information);
if($result) {
echo "Success";
}
$contact = $address_book->get_contact($id);
in this way, my controller methods are handling the in and out with the Models. there will be no views, cause i just have to return the data/result from the Models. and he can just use my "API" functions.
is this possible?
cause i just know how to access the controller methods with the webbrowser. and i guess its not an option for him to use header(location) to access them.
all suggestions to make this possible are welcomed! even other approaches to let me use CI to develop. perhaps there already are best practices regarding this kind of cross framework collaboration?
thanks
MVC seems to have dispersed in its definition. This definition I will offer should be ideal for you.
Models are where you build your business end of the application. Operations such as create_contact, delete_contact, and get_contact belong in the model layer. The model layer is what builds your application API and should be entirely independent.
Consider the controllers purely as the user's puppeteers. Controllers accept user input - the validation, sanitation, and whatnot may be done elsewhere - and invokes the API you've already setup in the model layer. Also, controllers then specify what view to use - however complicated or simple your presentation layer is.
The presentation layer usually isn't the difficulty. As long as you are only using read operations in the view you should be fine.
To clarify, if a user wants to create a new contact, the controller may need a method called create_contact that accepts the appropriate input. However, the actual operation of creating the contact must be done in the model layer. This will allow your other developer to reuse that same operation in a completely different application by loading your model, which was already designed as an independent entity.
I'm currently rewriting an e-shop - but only the client side, i.e. the CMS remains mostly in tact. I am not using a pre-built framework, as the system has to retain backwards compatibility with the CMS and I have to have full freedom of the structure of code.
The new system is purely MVC based and I have a Bootstrapper which loads controllers based on the current uri and the latter use models for the real work - both with sessions and the database.
tl;dr It's my first project without a pre-built framework.
I am very inexperienced when it comes to design patterns. I know how do most of the popular ones work but have had never put them to use.
Now I am suspecting code smells because all of my models are classes that consist purely of static methods. I can find no advantages of doing them in a different manner. I routinely need some of the methods in various places through out the code. I.e. I need to fetch the logged in user in the main layout, check user rights to see current page in the bootstraper, display user panel by the controller. I'd need to re-instantiate an object each time or keep a global one if I wasn't using statics. There also won't be a need for more than one such class at a time.
I must be missing something, because even though I use OOP, some my classes are just meaningless containers for their methods (and sometimes a couple of private variables). I could have just been using PHP4 and simple functions.
Any comments or advice would be highly appreciated.
EDIT: in spite of all these educated answers, I remain unconvinced. Even though it's most probably because of my lack of experience, I still don't foresee anything going wrong with the current setup. I mean I don't even fathom a situation where I'd have any inconveniences due to the code architecture as it is now. I hope I don't get a harsh lesson when it's too late to change anything...
You are right, it's a code smell and everybody will tell you it's baaaad.
So here I suggest rather to make a self-assessment of the severity of the problem:
Do you have classes with many getter and setter?
Are your static functions like the one below?
If yes, try to move the logic in the class MyClass that will be already way more OO. That's a classic mistake from procedural/scripting world.
static void myMethod( MyClass anObject )
{
// get value from anObject
// do some business logic
// set value of anObject
}
Do you have a lot of global state, such as data you fetch from the current session?
If yes, make an assessment whether you want to change it. The OO way would be to pass the session down the call chain. But in practice, it's convenient to access the session as a global object. But it impedes testability. Try to remove some global state and turn that into regular object that you pass and manipulate in methods.
Make this assessment, and try to identify utility classes, services classes and the business objects. Utility class are helper classes with utility methods (e.g. formatting, conversion, etc.) which can be static. Service class do some business logic but they should be stateless and one instance suffice. Business objects are user, products, article, etc. is where you must concentrate your effort. Try to turn plain data into objects with embed some behavior.
Have a look at should entity be dumb. Even if it's for java, the concepts are general.
EDIT
Here is my analysis based on your comment:
You don't have a domain model with entities. You manipulate the database directly.
What you call your model, is what I call services and is where you perform the business logic that manipulate data. Service classes are stateless, which is correct. As you pointed out in the question, you then either need to constantly re-create them, create one global instance, or use static methods.
The OO paradigm would say that you should try to have a domain model where you map your database with entities. At least have an anemic domain model where entities are dull data container that are loaded/persisted in database. Then the OO paradigm would also say to put a bit of logic in the entities if possible.
It would also say to turn the services into objects to ease composition and reuse. If it was the case you could for instance wrap all services with an interceptor to start/stop transactions or do some security check, which you won't be able to do with static methods.
What you describe (no entities + stateless procedural services) is not considered a great OO design. I would suggest you introduce an anemic domain model at least and DAO. Regarding the sateless procedural services, this is actually the reality of many web applications -- if you don't need more you can stick to it.
My 2 cents
If you are mainly only using static classes then you've really taken out the object out of object oriented programming. I am not saying you are doing things incorrectly, I am saying maybe your system shouldn't lend itself to OOP. Maybe it is a simple app that requires some basic utility functions (sends email, etc). In this case most of your code becomes very procedural.
If you are dealing with databases you could have a static db class, and a simple business layer, and your php app interacts with your business layer which in turn interacts with your database layer. This becomes your typical 3-tier architecture (some people like to refer to this as 4 t-iers and seperate the actual database from the data layer, same thing).
If you are not really calling methods that require an object than what is the point of all of these static classes, just a question to ask yourself.
One thing you may notice is that if you plan on doing any kind of unit testing with mocking/stubbing you are probably going to have a hard time since static classes and methods are not easy to mock, stub or test.
I would be cautious about using static variables and classes in web applications. If you really must share an instance between users, then it should be ok to have a single instance (lookup "Singleton" design pattern).
However, if you trying to maintain state across pages, you should do this through either utilising the ViewState or by using the Session object.
If you were to have a global static variable, you could have a situation where concurrent users are fighting to update the same value.
Short answer: It's ok but you are foregoing the benefits of OOP.
One reasoning behind using objects is that most of the time there is more than one type of object that performs a role. For example you can swap your DBVendor1 data access object with a DBVendor2 data access object that has the same interface. This especially handy if you are using unit tests and need to swap objects that do real work with dummy objects (mocks and stubs). Think of your objects with the same interface as Lego bricks with different colors that fit together and are easily interchangeable. And you simply can't do that with static objects.
Of course, the increased flexibility of the objects comes at a price: The initialization of the objects and putting them together is more work (like you wrote) and leads to more code and objects that put together other objects. This is where creational design patterns like builder and factory come into play.
If you want to go that route, I advise you to read about dependency injection and using a DI framework.
Technically there is nothing wrong in doing it. But practically you are loosing lot of the benefits of object oriented programming. Also write the code/functionality where it belong to.. for example:
user.doSomeTask()
on the user object makes more sense than
UserUtils.doSomeTask(User user)
Using OOP concepts you abstract the functionality where it belongs to and in future it helps you change your code, extend the functionality more easily than using the static methods.
There are advantages to using static methods. One being that since you cannot inherit them they perform better. But using them all of the time limits you. The whole OOP paradigm
is based on re-usability of base classes thorough the use of inheritance.