Should a class kill the application? - php

Consider a web application that is made up of several classes. Each class has its own client - program/script that creates an object of the class.
The question is this, when a client creates an object or uses a method of a class/object, and something goes wrong in the class, should:
class terminate the application
class return a false and it's up to client to take proper action
throw and exception
Which one of these is considered best practice?

Throw an exception. It's the cleanest way to handle the abnormal situations.
Never terminate the application from inside a function of a method. They should not know about the context where they run. Throw an exception (or return FALSE/NULL/empty string/whatever is most appropriate for your application) and let the higher level code (the caller) decide how to continue.

I'd say it depends on a size and complexity of your code base, you could use any of those methods depending on a case, but the most professional one to use would be class return a false and it's up to client to take proper action.
With your own debug class it could decide what to do next, i.e. destruct class instances, close file handles, flush buffer, like I said depends on your code base. It's a good habit to handle errors with a custom error/debug class.
Hope that helps you.

Depends why it failed i guess. without knowing what the situation is, i would say to display a 404 page.

Related

Logic inside constructor

Is it a good idea to have logic inside __constructor?
public class someClass
{
public function __construct()
{
//some logic here
}
So far I thought that it is fine; however, this reddit comment suggests the opposite.
As #Barry wrote, one of the reasons is related to unit-testing, but it's just a side-effect.
Let's take the worst case scenario: you have a "class", which only has a constructor (you probably have seen such examples). So ... why was it even written as a class? You cannot alter it's state, you cannot request it to perform any task and you have no way to check, that it did what you wanted. You could as well used a linear file and just included it. This is just bad.
Now for a more reasonable example: let's assume you have a class, which has some validation checks in the constructor and makes a new DB connection in it. And and then it also has some public methods for performing various tasks
The most obvious problem is the "makes a new DB connection" - there is no way to affect or prevent this operation from outside the class. And that new connection is going off to do who-knows-what (probably loading some configuration and trying to throw exceptions). It also constitutes a hidden dependency, for which you have no indication, without inspecting the class's code.
And there is a similar problem with code, that does validations and/or transformations of passed parameters. It constitutes hidden logic (and thus violating PoLA. It also makes your class harder to extend, because you probably will want to retain some of that validation functionality, while replacing other part. And you don't have that option. Because all of that code gets run whenever you crate a new instance.
Bottom line is this - logic in constructor is considered to be a "code smell". It's not a mortal sin (like using eval() on a global variable), but it's a sign of bad design.
No it isn't a good idea for automated testing. When testing you want to be able to "mock" objects that allow you to control the logic especially in terms of interfaces. So if you place logic in the constructor then it is very hard to test as you must use the real object.
here is a fantastic talk with much more detail on why not to put logic in constructor (google tech talk by Misko Hevery)
https://www.youtube.com/watch?v=RlfLCWKxHJ0
I think this question is little bit unclear because i don't think that __construct is bad place to logic, the question is what kind of logic you have here? Some kind of logic can be placed in constructor but another must not be present in constructor. For example Symfony Response - constructor contains logic, but this logic is necessary for this object, and this constructor doesn't make some implicit actions. This constructor doesn't print content to output or something else - so this is good example (as for me)...
Also it is important to understand what you object must to do, if it will be immutable object - constructor can have little bit another view...
Also it's important to follow SOLID and appropriate design pattern...

SUT - Testing Internal Behaviour TDD

I have a question about testing requirements.
Let's take example:
Class Article {
public void deactive() {//some behaviour, which deactives article}
}
I have in my requirements, that Article can be deactived. I will implement it as part of my Article class.
Test will call deactive method, but what now? I need to check at the end of the test, if requirement was fulfilled so I need to implement method isDeactived.
And here is my question, if I really should do it? This method will be only used by my test case, nowhere else. So I am complicating my class interface, just to see assert, if is really deactived.
What is the right way to implement it?
It's generally considered ok to add test hooks to a class. It's better to have a slightly more cluttered interface and know your class works than it is to make it untestable. But there are some other solutions.
If you're ok making your method protected or package-private, you might be able to use something like Guava's #VisibleForTesting annotation. Languages other than Java might have other similar libraries.
You could also inherit from Article to get access to private fields.
class ArticleTest extends Article {
#Test
public void deactiveTest() {
this.deactive();
assertTrue(this.isDeactive);
}
}
This all assumes you have some field you're using to mark whether the object is active or not.
It might be the case that you're causing some side effects, like calling the database, and a couple of services to say you're deactivating that article. If so, you should mock the collaborators that you're using to make the side effects and verifying that you're calling them correctly.
For example (in java/mockito like pseudocode):
#Test
public void deactiveTest() {
Article underTest = new Article(databaseMock, httpMock); //or use dependency injection framework of your choice...
underTest.deactive();
verify(databaseMock).calledOnce().withParams(expectedParams);
verify(httpMock).calledOnce().withParams(expectedParams);
}
A final possibility, if that field affects the behavior of some other method or function, you could try (again in pseudocode):
article.deactive()
result = article.post() // maybe returns true if active, else false?
assertFalse(result)
This way, you're testing the resulting behavior, not just checking the internal state.
It sounds like you are writing a test along the lines of:
assertThatCallingDeactiveMarksArticleAsDeactivated
With an isDeactivated method, this test becomes trivial, however as you've said, your Article class doesn't contain this method. So, the question becomes should it have that method. The answer really depends on what it really means for the Article class to be deactive.
I would expect and active Article to behave differently in some way from a deactive Article. Otherwise, it seems like the state change doesn't have a reason / there is nothing to test.
To give a practical example, looking at it from the perspective of a client of the Article class. Something triggers the call to deactive. It may be something as simple as the user clicking on a Deactivate button/link on the user interface, which calls through to the Article class. After this call, I'd expect the user interface to reflect in some way that the Article was deactive (for example by greying out the button/link), but for it to do that, the UI needs to be able to read the state of the Article, which brings us back to the question how does it do that and/or why isn't the isDeactivated method needed by the current code?
Without knowing more about the implementation of the deactive method (does it simply set a flag, or does it call out to other code in an observable way) and how the state change effects the behaviour of Article and it clients it's hard to give a more concrete response.
Ideally you don't want to test the internals of a method or class, as this makes tests brittle and tightly coupled. If you refactor the production code, your test has a higher change of also needing to be refactored, thus going the benefit of the test. You want to try and test the classes behaviour as a whole (i.e what does calling deactivate do)
Check out Kent Beck's 4 rules for simple design (in priority order).
1) All Tests Pass
2) Expresses Intent
3) Eliminates Duplication
4) Fewest Elements
The last rule is that a system shouldn't be any larger than it needs to be, which is where your question falls. Given this is the least important element and that its better to 1) pass a test and 2) express intent, it would be acceptable (in my view) to simply add an isActive() method.
This also makes the class more useful and generic, as is you deactivate something, it seems logical to be able to verify its state.
Also as previously mentioned, there must be an effect of calling deactivate which in itself should be tested, so try and test this - It maybe an Integration Test is better placed, or you have to mock or stub another class.

PHP logging approach across classes

I've created a simple class LogHelper with a static method that I call within my application. I can call it as follows:
LogHelper::writeToErrorLog($config->getLogPath(), $exception); or
LogHelper::writeToErrorLog($config->getLogPath(), $exception, $config->getLogFile);
The writeToErroLog method will generate a log filename if one isn't passed into it.
I have another class called Config, which basically takes an XML file and exposes the values via getters & setters. This is initialised at the start of the app & contains the log path where the error logs need to be written to.
My requirements are that I create one log file with the same filename per run of the application. When the app ends the logs, if populated, will be emailed.
My application has numerous other classes for DB, parsing data, formatting data, etc... all requiring logging at some point. The majority of my errors will come from exceptions thrown which will bubble up to the parent class, caught & handled by the LogHelper. There will be several cases where I don't want to throw exceptions and will just want to log information or errors.
My concern is that I feel like I'm constantly passing the config to every class that requires logging, which feels wrong. In addition I only want to be setting the filename for the error log once. Is there any best practice way of approaching this?
TIA
Stuff
Have you considered using set_exception_handler()? You wouldn't have to put the logger in every class, it would simply handle all uncaught exceptions. You could call it within your bootstrapping process or some other application initialization spot as such:
set_exception_handler(array("MyClassName", "functionNameHere"));
Inside that function you could call LogHelper::writeToErrorLog().

How to create write-once properties?

I'm stuck with a general OOP problem, and can't find the right way to phrase my question.
I want to create a class that gives me an object which I can write to once, persist it to storage and then be unable to change the properties. (for example: invoice information - once written to storage, this should be immutable). Not all information is available immediately, during the lifecycle of the object, information is added.
What I'd like to avoid is having exceptions flying out of setters when trying to write, because it feels like you're offering a contract you don't intend to keep.
Here are some ideas I've considered so far:
Pass in any write-information in the constructor. Constructor throws exception if the data is already present.
Create multiple classes in an inheritance tree, with each class representing the entity at some stage of its lifecycle, with appropriate setters where needed. Add a colletive interface for all the read operations.
Silently discarding any inappropriate writes.
My thoughts on these:
1. Makes the constructor highly unstable, generally a bad idea.
2. Explosion of complexity, and doesn't solve the problem completely (you can call the setter twice in a row, within the same request)
3. Easy, but same problem as with the exceptions; it's all a big deception towards your clients.
(Just FYI: I'm working in PHP5 at the moment - although I suspect this to be a generic problem)
Interesting problem. I think your best choice was #1, but I'm not sure I'd do it in the constructor. That way the client code can choose what it wants to do with the exception (suppress them, handle them, pass them up to the caller, etc...). And if you don't like exceptions, you could move the writing to a write() method that returns true if the write was successful and false otherwise.

What things are best not done in a constructor?

I started off by drafting a question: "What is the best way to perform unit testing on a constructor (e.g., __construct() in PHP5)", but when reading through the related questions, I saw several comments that seemed to suggest that setting member variables or performing any complicated operations in the constructor are no-nos.
The constructor for the class in question here takes a param, performs some operations on it (making sure it passes a sniff test, and transforming it if necessary), and then stashes it away in a member variable.
I thought the benefits of doing it this way were:
1) that client code would always be
certain to have a value for this
member variable whenever an object
of this class is instantiated, and
2) it saves a step in client code
(one of which could conceivably be
missed), e.g.,
$Thing = new Thing;
$Thing->initialize($var);
when we could just do this
$Thing = new Thing($var);
and be done with it.
Is this a no-no? If so why?
My rule of thumb is that an object should be ready for use after the constructor has finished. But there are often a number of options that can be tweaked afterwards.
My list of do's and donts:
Constructors should set up basic options for the object.
They should maybe create instances of helper objects.
They should not aqquire resources(files, sockets, ...), unless the object clearly is a wrapper around some resource.
Of course, no rules without exceptions. The important thing is that you think about your design and your choises. Make object usage natural - and that includes error reporting.
This comes up quite a lot in C++ discussions, and the general conclusion I've come to there has been this:
If an object does not acquire any external resources, members must be initialized in the constructor. This involves doing all work in the constructor.
(x, y) coordinate (or really any other structure that's just a glorified tuple)
US state abbreviation lookup table
If an object acquires resources that it can control, they may be allocated in the constructor:
open file descriptor
allocated memory
handle/pointer into an external library
If the object acquires resources that it can't entirely control, they must be allocated outside of the constructor:
TCP connection
DB connection
weak reference
There are always exceptions, but this covers most cases.
Constructors are for initializing the object, so
$Thing = new Thing($var);
is perfectly acceptable.
The job of a constructor is to establish an instance's invariants.
Anything that doesn't contribute to that is best kept out of the constructor.
To improve the testability of a class it is generally a good thing to keep it's constructor as simple as possible and to have it ask only for things it absolutely needs. There's an excellent presentation available on YouTube as part of Google's "Clean Code Talks" series explaining this in detail.
You should definitely avoid making the client have to call
$thing->initialize($var)
That sort of stuff absolutely belongs in the constructor. It's just unfriendly to the client programmer to make them call this. There is a (slightly controversial) school of thought that says you should write classes so that objects are never in an invalid state -- and 'uninitialized' is an invalid state.
However for testability and performance reasons, sometimes it's good to defer certain initializations until later in the object's life. In cases like these, lazy evaluation is the solution.
Apologies for putting Java syntax in a Python answer but:
// Constructor
public MyObject(MyType initVar) {
this.initVar = initVar;
}
private void lazyInitialize() {
if(initialized) {
return
}
// initialization code goes here, uses initVar
}
public SomeType doSomething(SomeOtherType x) {
lazyInitialize();
// doing something code goes here
}
You can segment your lazy initialization so that only the parts that need it get initialized. It's common, for example, to do this in getters, just for what affects the value that's being got.
Depends on what type of system you're trying to architect, but in general I believe constructors are best used for only initializing the "state" of the object, but not perform any state transitions themselves. Best to just have it set the defaults.
I then write a "handle" method into my objects for handling things like user input, database calls, exceptions, collation, whatever. The idea is that this will handle whatever state the object finds itself in based on external forces (user input, time, etc.) Basically, all the things that may change the state of the object and require additional action are discovered and represented in the object.
Finally, I put a render method into the class to show the user something meaningful. This only represents the state of the object to the user (whatever that may be.)
__construct($arguments)
handle()
render(Exception $ex = null)
The __construct magic method is fine to use. The reason you see initialize in a lot of frameworks and applications is because that object is being programmed to an interface or it is trying to enact a singleton/getInstance pattern.
These objects are generally pulled into context or a controller and then have the common interface functionality called on them by other higher level objects.
If $var is absolutely necessary for $Thing to work, then it is a DO
You should not put things in a constructor that is only supposed to run once when the class is created.
To explain.
If i had a database class. Where the constructor is the connection to the database
So
$db = new dbclass;
And now i am connected to the database.
Then we have a class that uses some methods within the database class.
class users extends dbclass
{
// some methods
}
$users = new users
// by doing this, we have called the dbclass's constructor again

Categories