So I have a large class that I'm refactoring to be more flexible.
well over 100 configurable properties (variables) in a INI file. Some are dev settings and others are production settings.
Currently I use a environment flag to pull the INI settings I need (either dev or prod).
All the INI fields are mandatory and must be set. (currently using setters for this).
So what makes more sense?
A: to keep the current setup
B: Move to another type of configuration setup (like xml or something)
C: Move all settings into the script itself and remove the INI parsing and validation code (setters)
D: suggestions?
Bonus question:
I was reading this over the weekend: http://berryllium.nl/2011/02/getters-and-setters-evil-or-necessary-evil/ and wanted to know how I could follow more of this type of development style but confused as how to not use getter/setter functionality with setting mandatory fields? I understand the need to getters/setters and wanted to know if I'm implementing them correctly?
I use the INI for stuff like DB settings, validation limits (think spending limit of $100 but could change), large array (static values like the 50 US States but with the ability to add US territories as well)
If you want to keep settings
readable, keep the current setup or
move settings into PHP script (but do
not hardcode them into classes).
If
you want to increase performance -
use JSON format or PHP script -
json_decode works faster, PHP script
works faster and can be easily cached
by APC.
As variant, you can parse
the settings file once and put all
settings in cache (APC or memcache).
Also. I think nobody cares, but I have my opinion about getters and setters :)
Getters and Setters aren't evil. Idea of Encapsulation is not just hide fields, but hide, how class works. Getters and setters can be declared in interface, so you can replace one object by another - and it is what for encapsulation was invented!
Let's take example from article of Berry Langerak - withdraw and deposit it's setters. All this code can be successfully done in setBalance method, almost nothing will be changed. All these checks, comparison - it's usual work of setters.
Why public fields are evil? Because object can't control their changing and because they can't be declared in interfaces. Getters and setters can do it, so it's perfect tool of OOP.
Accessors can be written silly, of course, but it doesn't mean that they are evil. Any method in the class can be written silly.
Interesting question.
I highly doubt that all of those variables are/could be different between your development area and your production area. Not every variable that you might change when debugged would have to be stored inside a config file.
I would advice using constants for the most variables.
You have auto complete, tons of IDE options and it's easily editable. Not to mention it's more logic to split them up into different files then to parse tons of ini's.
Related
I've got this Config-class that I use in my PHP5 application to load & parse my static config. This far I've managed to keep the class from being a singleton/registry and instead passed the instance of the Config class around to wherever it's needed with the help of Dependency injection.
But now as I need to set/make changes in my Config during runtime at one place, my changes aren't reflected globally and being far from a specialist with the use of the static modifier in PHP, I need to ask:
What is the best way to ensure that changes to the properties in my Config-class are reflected throughout my application without making the class into a singleton? Can I just make the variable holding the config data static?
This far I've managed to keep the class from being a singleton/registry and instead passed the instance of the Config class around to wherever it's needed with the help of Dependency injection.
If you pass the same instance of your Config class to every part of your application and you change a setting it should be reflected everywhere else.
In case you are creating multiple objects of the class (and parse that config file every time?!) you might want to stop doing that. It's possibly wasteful and I'd say it is confusing.
So if you create only one and pass that around everything should be fine.
Under the assumption that you create multiple instances of the object that only should exist once:
If you are able to "fix" your architecture to allow you to do that: Do so.
If you can't to that... well.. creating a static property to hold your values in a class that you can have multiple instances off is, at least in my book, a major wtf factor. If you can't fix (meaning it's to much off a hassle to do so) just "break" it in an expected way so other people don't trip over it.
I'd rather have a singleton than something that creates all the issues with singletons and also lies about being a wrapper for a global variable.
Blindly avoiding design patterns because you hear on Internet forums that they're bad is about as much an anti-pattern as singletons are in general. If a tool is right for a job, then it's right.
Look at your question, you're trying to emulate singletons through a complex multi-update system for God's sakes... And just so you know, making a class static is essentially turning it into a singleton, albeit an insecure one that can be overwritten at any time.
TL;DR: Think for yourself and use the right tools; make your config class a singleton.
Here I am writing a small app with the sole intent of acquiring better OOP/testable code habits. And loving it, btw!
I am striving to assimilate the methodology behind developping 'testable code', mostly by reading posts from unit testing evangelists such as Sebastien Bergmann, Misko Hevery and Giorgio Sironi.
Among the hardships I assimilated is the misuse of static methods, objects that depend on objects that depend on objects. Currently, I am stuck on global wide constants. At the start of my application I load one single CONSTANT that simply sets the application mode in debug or prod:
/**
* APP_MODE values:
*
* PROD Production, no errors displayed email sent on error, logs to
* logs/app-<date-time>.log.
*
* DEBUG: All warnings and errors displayed, emails disabled and log messages
* sent to console. Whether in-memory modifications to configuration
* data are allowed
*/
define("APPMODE", "DEBUG");
How can one test app classes for proper error handling depending on the state of this constant?
At first my thought was to simply move the global constant to a class constant instead in my init class and that solves the case for this particular class, but I am not satisfied with this procedure. I mean, should one simply avoid sitewide constants that are not "truly" constants in the strict sense of one possible value always?
I can't imagine testers have to write 2 test suites for every class, ie initClassDebugTest.php and initClassProdTest.php unless phpUnit can somehow reset global state? Should global constants used this way be avoided? I have a weird gut feeling I should not use a constant here at all. I would be very curious to know how test savy coders out there would handle global defines with 2 possible values at runtime.
It mainly depends on how you create your objects and how many classes access this APPMODE.
Let's see what APPMODE does:
* DEBUG: All warnings and errors displayed, emails disabled and log messages
* sent to console. Whether in-memory modifications to configuration
* data are allowed
Something like this usually gets solved by passing in "DebugLogger" and "DontSendEmailMailer" to the classes that need to send mail.
By doing this you only need a few factories (or whatever you use to create your object graph) that need to know about "production" vs "development".
The classes that do your actual business logic should not know if it's run in production or not. That would mean the developer of each class would have to care about that and every class would need to be changed if you .. say.. have a "staging" environment. It introduces lots of global state that, like you discovered, is hard to test.
If errors should be displayed or not to be decided in your models in your php.ini or in your application bootstrap and should not concern the rest of your application.
I'd start of moving that "debug" functionality out of classes that need your APPMODE setting and move that into to dedicated (logging, mailing, ...) classes. The real thing (that actually sends mail) and the debug thing (that maybe writes mails to disk?). Both of those classes can be tested properly (testing a null logger is pretty easy ;) ) and you need to make that switch only a few times.
if($config->evironment() == "debug") {
$logger = new DisplayEverythingLogger();
} else {
$logger = new OnlyLogErrorsToTextfileLogger();
}
$neededModel = new ClassThatDoesActualWork($logger);
$controllerOrSomething = new ControllerOrWhatEveryDoesYourWorkflow($neededModel);
$controllerOrSomething->dispatch();
and so on. You can reduce the amount of global state step by step until you get rid of the define and only have a configuration setting.
When it comes to testing the class that does work you now won ether way because the logging is injectable and you can pass in a mock for testing.
So far for a first idea.. if you think that doesn't work for you maybe provide an example where APPMODE is used
Use phpunit's --bootstrap option. It runs the given file prior to any tests being done.
I am working on code re-factoring of configuration file loading part in PHP. Earlier I was using multiple 'ini' files but now I plan to go for single XML file which will be containing all configuration details of the project. Problem is, if somebody wants configuration file in ini or DB or anything else and not the default one (in this case XML), my code should handle that part.
If somebody wants to go for other configuration option like ini, he will have to create ini file similar to my XML configuration file and my configuration manager should take care everything like parsing, storing in cache. For that I need a mechanism lets say proper interface for my configuration data where the underlying data store can be anything( XML, DB, ini etc) also I don't want it to be dependent on these underlying store and anytime in future this should be extensible to other file formats.
Assuming you're wanting to use a class to handle all this, you have 3 options:
Have a base class called something like, ReadConfigurationBase then 3 implementation classes, ReadConfigurationXML, ReadConfigurationINI, and ReadConfigurationDatabase and you'd have to choose the right one
Same as above, but using a factory to choose, based off of something passed in. Like if you pass config.xml it would know to return ReadConfigurationBase implemented using ReadConfigurationXML
Have a class called ReadConfiguration and it acts as step 2, but creates, contains, and owns, the 3 other classes.
The 3 non-base classes would simply know how to read that type of configuration file, and pass the information back in a generic manner. think along the lines of an interface: You know you can get the data, but you don't care how.
I'd suggest option 3, since it would make life easiest. You would have to do a little bit of modification every time you want to add a storage method, but that would just be adding a little bit into the ReadConfiguration class.
There is a way you could make it 100% dynamic, but that would complicate matters, and I don't think you really need it for this.
Have a look at Zend_Config. It provides adapters for Arrays, Xml and Inis. Like all components in Zend Framework, it can be used isolated from the remaining Framework. Even if you don't want to use it, it's well designed and you might get a few ideas for your own config manager from it.
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.
From my basic understanding in Object Oriented coding, PHP in my case, you want to make all your classes pretty much independent of one another. I have just started my object oriented application so it is a great time for me to make changes in it's early stages.
Here is my situation where I break this rule or whatever you want to call it.
I have a sessions class that has a set method which lets me set variables to a php session and I have a view method which let's me view the value of a value that has already been set using the set method. So far it probably sounds OK but then on every page of my site I need to access session data or the session objects I should say. But then besides every page using the session objects, I also use them in all my classes that need the session value. I believe this is where I have messed up, because now all these other classes rely on the session class.
Any ideas on if this is wrong and if it is, what are some ways I can avoid it but still have access to the session data in the other classes and still have my classes be portable plug-n-play into other future applications?
This kind of relationship is called dependencies or coupling. You generally want to reduce coupling in any application (Object oriented or not). Just how to do it is perhaps the most important skill of a programmer, and can't really be summarised into a few rules.
However, at the most basic, you should try to distinguish between essential dependencies and accidental dependencies. The former is an un-solveable problem, so you shouldn't try. For example, if all your pages need access to the session, then you really can't help giving them that. But if they only need it some times, than you could try to factor your application so that this is addressed.
Another important point is to minimise the interfaces between components. If x is a subset of X and Y relies on x, then you shouldn't pass X. This is often a place where there is room for improvement.
Think about what those other classes need in order to function in terms of your domain model. Session data is an implementation detail that shouldn't affect how you design your other classes. The session object might have 100 properties, but not every class needs all 100 of those properties to work. They don't need to know if that data was persisted in sessions, cookies, flat-files, databases, or on a satellite outside earth.
A great resource I've found useful while designing classes is this book, and specifically chapter 6, "Working Classes" for your question.
You could add one level of abstraction making it WorkingClass > StoringMapper > Session, with WorkingClass only calling StoringMapper. As such, you could easily "map" the storing process to any other class than Session (for example DatabaseSession) without any changes to WorkingClass.
I've written some code for it in response to another question: Advice on framework design
Generally, one class using another is pure basic OO and what you'll want. Using Interfaces is a way to have your concrete logic isolated while letting other classes use this component in a uniform way. A simple and common way is to use a Factory or Abstract Factory instead of directly calling constructors. You should also have a look at the Inversion of Control and Dependency Injection (DI) paradigms. Here's a rudimentary example that could help you with your problem (but be aware, the author mixes up between Factories and DI).
A not to complex solution would be to extract an interface from your Session class. Think of what a caller would need from a session object. Then realize the interface in your class. You'll maybe want to make this class a Singleton (a class for which only one realization exists at runtime). Then, create a factory that instanciates your script's components. Pass the session instance to the components in the factoring method.