You have a class, that perfectly fits to be an abstract, but this class cannot work normally without data supplied from derived class. It's not convenient to pass all data to constructor because not all of it may be needed, and many of them can be dynamic (result from child function).
What are the best practices to compose such structure?
Or is it a bad design in the first place?
Declare abstract functions, that child must implement?
Declare normal functions, that are overriden in child class?
If there is a reasonable default behaviour of the function that can be relied on in a majority of children, it can be implemented as a normal one. Otherwise (no default behaviour and/or most children have to override it), it's better to declare it as abstract. The side effect is that you never forget to define it in a child class because failure to do so will be immediately reported.
The other opportunity is the use of containers (for example, arrays) for the data that are specific to the child classes, but still are subject for general checks or other processing that can be done in the common ancestor. This way you define a variable that holds the data, but the data itself is filled in the children. The code in the parent class can iterate over this container and do some routine work on all the elements.
Related
I know this is kind of a question of faith and has been asked many times before, but the answers I've found were either too general, didn't apply to my use case, or didn't satisfy otherwise.
I'm currently building an application that uses classes as representation for database tables. These classes don't offer any methods of their own, I've written a parser class for each one that works with their objects and returns the data in the format I need, which makes the parent classes nothing more than data storages and makes a nice distinction between data and logic.
Now, the consensus in OOP seems to be that you always have to use getters and setters instead of accessing class attributes directly.
An argument I've often heard is that using getters and setters gives the possibility of extending those functions later on, but in my opinion this goes against YAGNI and some other concepts I can't remember the name of right now - that a method should do exactly what you would expect from its name. If I wanted to do something more than simply set a value, I would write a new method, not put that into my setter method, since that one is, per definition, only supposed to set attributes. So I might as well skip the setter and just access the attribute directly.
Another one is that you can put validation in your setters, which I already do in my API that accesses these classes. In my opinion you shouldn't just pass values and have the object tell you if your value is okay or not, but instead validate those values first before you pass them to the object.
I do understand the purpose of private/protected attributes in "usual" classes, but when the class is literally just a data container without any methods, is this really needed? In other words: is there a glaring disadvantage to using public values, when the setter methods for those (were they private) would all just look like public function getAttr($attr) { $this->atrr = $attr; } anyway?
You only need a data structure, but the only suitable PHP construct is the class.
Typically, in object-oriented analysis, design and programming, a class is a model of a thing or concept and it encapsulates any knowledge and/or behaviour of the thing or concept.
However, in the context of this question, encapsulation is not needed since you only require a data structure.
I am currently refactoring an application into multiple classes in an attempt to fulfill Single Responsibility Principle; however, many methods in the original mammoth classes use one common "metadata" object (bound as a class property) for their business logic.
For example:
if($this->metadata->applyTracking) {
// perform tracking logic
}
When I am separating these classes out, I am considering two options:
Passing this object to particular methods of the class, on case by case basis (Can be many occurences).
Adding this object as class properties (Many classes will have this property injected).
Making the object as a Singleton (I am wary of this approach since it may share the same fallbacks as globals)
Any advice on which path to take?
Method #2 seems to be best. I would inject an object repository, in which each member of the repository would be a different object that provides a different service. An example class can be found here: https://github.com/kenaniah/insight/blob/master/classes/registry.php
If you have inheritance in your code you may consider assigning it as a member in base classes and exposing the instance as a protected variable.
The Singleton really is more about whether or not the class is supposed to have only one instance in memory at a time, or if you will be instantiating the class many times.
It's hard to say for sure without knowing more about the how the object is being used, but I would probably suggest having a base class which defines the needed properties and then just inheriting that base class in any subsequent classes which need access to those properties.
quickshiftin just beat me to the punch though, haha.
I have three classes which basically do very similar things;
Store a record of an uploaded file.
Move and upload the file.
Set the status of the record to active or revoked.
One of the classes has an additional update method. Each class references a different table in the database because although some of the fields are common, there are a couple of fields extra in some of the tables.
As quite a lot of the functionality is common I think it may be best to extend a base class rather than duplicating a lot of the functionality.
My only quarrel is the construct function on the base class. As some of the fields in each table are additional I'm concerned this will prevent a base class.
I have thought of using an abstract class as this will allow me to extend on functionality whilst maintaining most of the things in one place. But it's the problem with the construct. Can I have an abstract class with no construct?
Any ideas?
If I understand you: You can have any class without __construct(). And you can always overwrite every method (except methods, that are declared as final) of a parent class in a child class.
I am sorry but I guess I do not completely understand your question. Anyway in inherited class you can always override the constructor and within it invoke the superclass constructor plus further stuff if needed.
I currently have a message system which writes to two tables, sent and received, which largely have the same schema.
I wrote a class called Message which populates the user inputted data before instantiating the two child classes which use a common method in Messageto set the rest of the properties and writing each to the database. The only significant difference is one field which is represented in the child class with its corresponding variable. All of the other properties are part of Message.
The thing is, Message has no purpose other than to provide common methods and properties for the objects created and facilitate access to the database class it's a descendant of.
Is this considered bad practice? Is the Message class monolithic or should I push it further and incorporate the child classes for the sake of one field? Would a better approach be to separate the classes entirely and have one for sent and one for received tables?
It is not bad design. You basically created an abstract class. Such classes are not intended to be instantiated but contain code that is common in several other classes.
You followed a principle: DRY - Don't repeat yourself.
Of course, if the difference is really really small, you probably make your design easier by putting everything in one class.
So you have class called Message that facilities common functions, and child classes (i.e.)
class SentMessage extends Message {
that facilitates specific tasks for a 'sent message'?
that makes perfect sense. It just depends how much functionality is seperate. If the only difference is that SentMessage and ReceivedMessage are marked 'sent' or 'received' - you'd be better off to have a getMessageType() function in your Message class instead. But if there is more complexity to it, then yes, you're on the right track.
at my working place (php only) we have a base class for database abstraction. When you want to add a new database table to the base layer, you have to create a subclass of this base class and override some methods to define individual behaviour for using this table. The normal behaviour should stay the same.
Now I have seen many new programmers at our company, who just override the method for the default behaviour. Some are so "nice" to put in all the default behaviour and just add there individual stuff where they like it, others kill themself trying to use the baseclass and their inheritor.
My first thought to solve this problem, was thinking about abstract methods that should be overriden by inheriting classes. But beside other arguments against abstract methods, "abstract" just does not show why the baseclass can't be used by its own and why these function should be overriden.
After some googling around I didn't find a good answer to implementing "real" virtual functions in php (just that there is a virtual function, that nearly kills all hope of a concrete implementation).
So, what would you do with this matter?
In PHP all public and protected functions are "virtual". You can prevent functions from being overriden by prepending the final keyword. (Or by making them private, but this is probably a bad idea).
In the design of the baseclass I would think of behaviors that subclasses would want to affect.
I would for example create empty functions like before_update() and after_insert().
function after_insert() {
// Virtual
}
Which the baseclass will call when an update/insert event occurs.
Maybe an is_valid() function which always returns true in the baseclass, and use the commentblock to describe what the consequences are when a subclass return false.
Hopefully this would give you some inspiration.
You can always use the "final" keyword to prevent some of the classes functions from being overridden if people are using the class in the wrong way.
It sounds to me like they are unable to acheive certain functionality hence overriding the methods. You may need to take a look at the design of your classes.
Without an example of the implementation of your base class, it's hard to give concrete info. But a few things come to mind:
Database abstraction is complex stuff to begin with. I understand that you want to keep it lean, clean and mean, but I think it's pretty darn difficult. You really have to take a thorough look at the specs of different DB engines to see what parts are general and what parts need specialization. Also; are you sure you don't have DB abstraction mixed up with the Table Data Gateway pattern, as you are talking about adding DB tables by extending the base class?
The methods of your current base class might be doing too much and/or are not general enough to begin with, if the extended classes are bending over backwards too keep it clean. Maybe you should break the base class interface methods up in smaller protected methods that are general enough to be reused in the overriding methods of the extended classes? Or vice versa: maybe you should have hooks to overridable methods in your interface methods.
Following from point 2: What's wrong with having an abstract class with some general implemented methods, and let your vanilla class (your base class) and other classes inherit from that?
Lastly, maybe you should just enforce an interface to be implemented, in stead of extending the base class?