I'm interested in a general concept, how would you organize your code ( what classes would you use) in the following context.
You have to deal with articles/nodes or content. The name doesn't matter the concept is the same. Each object has 10-20 attributes.
The problem starts when I need to work with this objects. In order to keep the code clean I try to move most of the operations in one or more classes.
The first method was to use a generic class called NodeManger. As you can imagine the methods stared pilling up so the only way to solve this was to start refactoring the code into several smaller classes with special purpose like NodeStorage, NodeConverter, NodeViewer, NodeBuilder and so on.
The operations you have to do on this collections seem few at the begging but in time they become bigger and bigger
- you have to store the nodes in different databases ( CMS ) , each of them has a different naming structure
- you have to extract the information from different tables
- you can get via API different inputs that with different names for the attributes but in the end it's the same object
- you have to select subsets, extract, filter, delete and so on.
So the questions are : Am I on the right track ? What would be an abstract structure you would devise in order to cope with these problems and be open to new operations that might appear ?
Remember that HasA (containment) relationships are GENERALLY a better choice than IsA (inheritance) relationships: it's probably better for your NodeManager class to contain several other objects which can act on data in various ways, rather than all of your objects extending objects which extend OTHER... well, you get the picture. It sounds like you're trying to design like this already, so I may just be preaching to the choir, but multiple inheritance gets out of hand really quickly, so it bears repeating.
With that said, sometimes you can't get away from inheritance, and most of the functionality that you're looking for can probably be implemented via abstract classes: create the abstract stubs of functionality you need, and then implement them on an as-needed basis for each of your various cases, so that you don't have to track that explicitly within the code (you mentioned different database connections with different naming conventions, for example).
It sounds to me that you need to look into Polymorphism and Inheritance.
http://php.net/manual/en/keyword.extends.php
http://php.net/manual/en/language.oop5.abstract.php
The above are good places to start looking.
Related
Brief Explanation
I am unsure about the structure that I have used for this group of websites. I have tried to share as much code throughout these websites as possible in order to minimise duplicate code and improve efficiency. However, I am not sure whether it is good OOP and would therefore like to hear some other views about it and whether or not I should change the structure.
Consider these websites:
www.domain.com
support.domain.com
clients.domain.com
export.domain.com
etc
I started by creating a class called class.domain.php. This class contains all of the global methods for the Web Application.
Then for each subdomain I created a sub class such as class.www.php, class.support.php etc.
If there are any large sectors of these subdomains then I create further subclasses to reduce the size of the parent class.
So effectively I have ended up with a family tree of classes like so:
Each class contains methods that are relevant to that particular site/section. The methods include things such as:
Gathering dynamic data and returning it to the page
Processing forms and sending emails (contact, support requests etc).
Security Token system
Login System
etc
My Questions
Not only do I want to know whether this structure is good, I also would like to know whether or not I should be using OOP for things such as processing 'contact' forms etc.
It just seems a bit extravagant (and hard to maintain) if I have individual methods for each form. The forms are too unique to be managed by one global method so they either have to be processed using a unique method for each form, or by having a script for each form that has nothing do do with the class (would be easier to maintain).
To summarize:
Is this structure an effective and good OOP structure?
Should I be processing my forms with individual methods within the classes or should I be writing individual scripts for each of the forms?
Thanks in Advance
Seems fine to me.
You can make things a bit more abstract maybe by implementing an interface or some abstract functions for the formprocess e.g.
You can write a BaseForm and all childs of BaseForm need to implement "validate()", "process()". That given you can always be certain that your classes implement those methods. So that you can use it in your action like
$form->validate($post_data);
if($form->isValid()){
$form->process();
} else {
$form->handleError();
}
since you have the possibility to write OOP, i suggest you to it since its also a lot easier to maintain it.
I still have to fiddle arround with older projects (like osCommerce) at my work and could scream when i see all the code duplications and if a single file contains about 3000-4000 lines of code with if-clauses spanning for a thousand lines you can very hard maintain it.
So for your own sake: stick to oop
In my application design, I usually map objects to the important tables in the database. The objects then handle everything relating to that data (including linkage tables). So I for example have built an Activity object, with properties like name and due_date, methods like load() and save(), and also methods like getParent(), getContributors() and getTeam(), which return (arrays of) other objects. Is this 'bad' OOP because it violates the Single Responsibility Principle?
It depends on the situation and the exact code you have: Your design might touch multiple responsibilities and still be a pretty nice OOP and maintainable.
Do you handle load() and save() in each class with similar code? Or do you delegate the task within load() and save() to other objects that are used for this functionality in several classes? That would be half-what following SRP and still be according to your design.
If not, your code really seems a bit smelly. To check whether it covers multiple responsibilities, ask yourself: what could cause changes to my class? In your situation, I would at least try to refactor the similar code in load() and save() in different classes to reach the situation described above, so that
maintainability is greatly improved,
you still do not need to change your clients' code.
Well .. its hard to tell at this stage. You could pastbin the whole class , but ..
Yes , it looks like bad OOP. You have same class responsible for interaction with database and domain logic. This creates two, completely different reasons for class to change.
You might benefit from exploring DataMapper pattern.
Maybe I'll just kick in the dark with this (cause I'm not an expert) but:
Methods load() and save() inside domain objects is called Active Record (Another description). This is not bad (altough I dislike it) because people that will maybe work after or with you will have less problems figuring out how to persist those objects.
About other methods. It's not that bad if it's in objects domain and it represents objects behaviour. If designed well it can be very good. Domain driven design encourages using rich domain model which is opposite of anemic domain model. An anemic domain model has domain objects that only have properties and getters and setters. So as long as it's in domain of your object, putting additional methods in it is not considered bad.
This is as far as I understand those concept from the books and articles I've read..
Hope it helps..
What you describe is an ActiveRecord and it's well known that it violates SRP. Also, ActiveRecord only works well when the table rows match the object closely. Once Impedance Mismatch gets too big, it will make changes to the system more difficult later.
It's not necessarily bad OOP, but it is a form of Technical Debt because of the lack of separation between persistence logic and domain logic. Violating any of the SOLID principles will usually lead to hard to change code, fragile code, non-reusable code.
A few of those debts are not an issue. It's when those debt accumulate interest, e.g. when they start to ripple into other design decisions. In other words, when you notice that it gets more difficult to change the system, try to pay back some debts, e.g. refactor to a more maintainable solution.
I think it's important to stop thinking that Model should be only layer between logic and database. Model can work with database and with other models, all logic should be in Models.
I think there is two ways:
your Model could return array of ID's in getContributors() method, and you could create new object (Factory maybe), which will convert these ID's to objects.
your Model could return array of objects, but without using new keyword, but through the Factory or Dependencies Container (I prefer DC).
I have a large class with lots of methods (25, interrelated of course). I'm not sure I should split it up and create a derivative and base class instead. I don't see any opportunity coming in the future for another class inheriting from the base. So what are the driving factors for breaking a large class down into smaller parts?
Yes, with 20+ methods, break it up.
Sometimes it needs experimentation.
Another option is to look at how to reduce the number of methods. For example do you have the same method (by name) taking different number and/or types of parameters? In that case you might look at commonalities between those signatures. This leads me to another suggestion.
If you have a method that takes more than - let's say 4 - parameters, then look at them and maybe there is an option to turn them into a class by themselves. This can result in some of the functionality moving out into the new class.
Look at the number of fields (= member variables) in your class. Can you group the methods in such a way that they operate largely on a subset of those member variables? Maybe you can turn these methods and the values they operate on into a new class.
what are the driving factors for breaking a large class down into smaller parts?
You should do it when it makes logical sense to do it in terms of separate objects. If all those methods you've defined truly do operate on a single object and couldn't logically be thought of as pertaining to different objects, then keep them in one.
I'm not sure I should split it up and create a derivative and base class instead
Not sure what you mean here. You would derive from a base class when you need an object that inherits some behaviours from a base class but modifies or adds others, but want your base class to remain as it is as well. You don't inherit just to break up your code into manageable chunks.
"Large Class" is a classic "code smell". See here: http://sourcemaking.com/refactoring/large-class
When you have a large class, it may or may not mean you have a good candidate for refactoring. That's what a "code smell" is... It may be your code is fine, but only a good hard look at it can you be sure.
Follow the advice given in the article I've linked. Even thought it wasn't written for PHP, the concepts and strategies still apply.
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.
This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
What are the benefits of OO programming? Will it help me write better code?
OO PHP Explanation for a braindead n00b
Just started learning/playing with creating classes in PHP and I'm wondering what pain do they solve? It seems like I can get the same job done with just a collection of functions that I include into the file. So my question is: Why should I use classes?
The Three Pillars of Object Oriented Programming. Learn them well:
http://codeidol.com/csharp/learncsharp2/Object-Oriented-Programming/The-Three-Pillars-of-Object-Oriented-Programming/
Encapsulation
The first pillar of object-oriented programming is encapsulation. The idea behind encapsulation is that you want to keep each type or class discreet and self-contained, so that you can change the implementation of one class without affecting any other class.
Specialization
The second pillar of object-oriented programming , specialization , is implemented through inheritance ; specifically by declaring that a new class derives from an existing class. The specialized class inherits the characteristics of the more general class. The specialized class is called a derived class, while the more general class is known as a base class.
Rather than cutting and pasting code from one type to another, the derived type inherits the shared fields and methods. If you change how a shared ability is implemented in the base class, you do not have to update code in every derived type; they inherit the changes.
Polymorphism
Polymorphism allows values of different data types to be handled using a uniform interface. The primary usage of polymorphism is the ability of objects belonging to different types to respond to method, field, or property calls of the same name, each one according to an appropriate type-specific behavior. The programmer (and the program) does not have to know the exact type of the object in advance, and so the exact behavior is determined at run time
See also:
http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming
http://en.wikipedia.org/wiki/Type_polymorphism
It's a way to view your code in a more intuitive, real-world way. (You package the data and all possible operations on that data together.) It also encourages encapsulation, abstraction, data hiding... What you're really looking for is the advantages of OOP.
Basically, classes allow you to put your data with the code - i.e. organization.
Also, classes allow your "followers" to customize your classes without rewriting your code, but rather creating new inherited classes.
Every class-based code might be rewritten with functions, but it would be much harder to understand.
Generally, its so that you can customize the behavior of that set of functions. Typically you have a bunch of functions that work in concert.
People who use these functions may want to only modify one of them for some special case. Or maybe you provide a class that forces the functions to interact in a certain why, but you can't define what they'll actually do.
A trite example: imagine if you had some library to check that some things didn't overlap.
class Comparator:
def Greater(self, left, right): pass
def Less(self, left, right): pass
def EnforceNoOverlap(self, comparator, left, right)
assert comparator.Greater(left, right) != comparator.Lesser(left, right)
It a way to make your code more granular, with proper data hiding, separation of concerns and some other best practices.
IMO using only functions in your code sooner or later leads to spaghetti-code that is hard to maintain and extend. It's harder to fix bugs, its harder to implement new features, because often there are lots of code replication.
Also you can't use polymorphism in your code design, so you can't work with abstractions.
the classes/object is the way of implementation object-oriented application design. it covered detailed in numerous OOAD/OOP books.