Reputation: 3576
After reading around how to build UML class diagrams and using SOLID principles, I've tried putting together a UML class diagram I'm happy with for a new Symfony project I'm going to start.
However, with the interfaces I've defined - for example:
I'm unclear if/how they should be implemented as Symfony abstract entities. From what I've read there seems to be conflicting opinions:
Symfony Docs: How to Define Relationships with Abstract Classes and Interfaces , however this seems to just be for when accessing abstract classes from other bundles?
Questions such as this where people advise against using abstract classes and to isntead create 'normal' entities (ie Professor and Student) - although isn't this then disregarding the benefits of SOLID?
Upvotes: 2
Views: 1594
Reputation: 5673
Your classes seem to represent ordinary (business) object types as defined in a UML class diagram representing a data model for an app. In your example, it's natural to consider the class hierarchy formed by the root class Person
with two subclasses Professor
and Student
in the data model. Now, when you have to implement such a data model (with subclasses and/or relationships/associations between classes) in some framework, the question is how to define corresponding model classes (also called "entity classes"), and the answer depends on the framework's support for these concepts.
Generally, when you have to deal with a class hierarchy in your app, and your OO framework supports inheritance/specialization between model/entity classes, then the main issues is how to map the class hierarchy to a set of tables in the underlying SQL DBMS as part of the Object-Relational Mapping (ORM).
In the data model, you wouldn't use interfaces, since they are an OO programming concept, and not a data semantics concept. However, in the data model you could define Person to be an abstract class, which implies that it does not have any direct instance and its only purpose is to define features (properties, methods and constraints) that are inherited by subclasses. Btw, this assumption/decision would imply that there are no other instances of Person
, except students and professors.
If your framework (e.g., Symfony) does not support inheritance from abstract classes, but some form of interfaces, then you may use an interface to get something like an abstract class defining abstract methods only. An interface Person
would define getters/setters for firstname
and lastName
.
Since in many cases, and also in the case of your simple example, the given class hierarchy is pretty simple, it's preferable to eliminate the sublcass relationships and reduce the conceptual class hierarchy of the data model to a plain set of classes using the class hierarchy merge design pattern. This avoids all the overhead that comes with defining interfaces and maintaining the relationships between them and the classes that implement them. It's equivalent to keeping the class hierarchy in your model/entity classes and using the Single-Table-Inheritance ORM pattern.
Upvotes: 1
Reputation: 584
You should look at the Inheritance Mapping section of the Doctrine documentation... It allows you to have an abstract "Person" class and then extend it to make it a "Student" or a "Teacher" there are a couple of different ways you can pull this off... the simplest of which is the SINGLE_TABLE
inheritance, which uses a "discriminator" in the database to know what type of an entity it is.
Upvotes: 1