Provide different abstract class to be extended in vendor - php

A vendor package I'm using has an abstract class that is extended throughout the package, I am trying to add a trait to the abstract class so it is used by each class that extends the abstract class.
What it looks like
abstract class AbstractClass {
}
and
class A extends AbstractClass {
}
What is the correct way to do this?

You can't extend a vendor class directly by modifying its source code (actually, you could but it's a very bad practice). Depending on the context, you have 3 ways to achieve something similar:
1 - Classic inheritance with some methods overriden. Do not forget contracts which allow you to substitute some Laravel classes with yours by implementing these contracts and customize dependency injection.
2 - Using a trait when 1 is not efficient. For example Laravel paginators, Illuminate\Pagination\Paginator and Illuminate\Pagination\LengthAwarePaginator. If you want to extend them with same functionalities, 1 asks 2 identic implementations whereas 2 needs only 1 implementation.
3 - The only way to extend without implementing custom classes is the use of macro/mixin methods from Illuminate\Support\Traits\Macroable. But it's only possible if the base class used this trait.

Related

I need to understand how to use a strategy design on a project PHP Project?

Note: it's a PHP Project
I have a situation where i use 2 API providers for my project.
They are like similar with what info they (API) provides.
I must set this right way since maybe tomorrow there will be some more APIs added.
So my project will need some methods.
Basic, here is what i have so far:
abstract class A {}// first api class, mostly contains API configs and call
abstract class B {}// second api class, also mostly contains API configs and call
//than first API has a sub classes of something like cars and trucks
class Car extends A implements ApiMethodsInterface {} // for the cars
class Truck extends A implements ApiMethodsInterface {} // for the trucks
//now second API has a sub classes for cars , trucks and spaceships
class Car extends B implements ApiMethodsInterface {} // for the cars
class Truck extends B implements ApiMethodsInterface {} // the trucks
class SpaceShip extends B implements ApiMethodsInterface {} // for the space ships
//they all have more or less similar methods
// so i used an Interface that all above classes
interface ApiMethodsInterface
//methods are
public function getModels()
public function getYears()
public function getPrice()
since every sub class implements this interface , i code by interface
Now, i have a situation, where SpaceShips has more methods to add, like getEquipment() and some more info, methods that other classes are not implementing.
Trucks also has more methods that others do not implements , like, hasTrailer(), trailerLength() etc...
My question is , what to do now, should i use Interface segregation, and add Interfaces to classes that implements those methods, and later check if object instantiated is having this method than run, else some exception, or to add missing models into the abstract classes A and B, and override methods into the classes that use those methods, or maybe there is even more good way of solving this. Quite new into Design Patterns btw...
Maybe i am overengineering but i really want to do this in a good way.
Thanks
It would likely help you to draw a diagram but we can talk through it.
It's completely normal for different implementors of an interface to have methods the others do not. The interface specifies the methods that all implementors share in common and when you code to the interface you just call those methods, not others the class may also declare. Any implementation of the iterface can be used interchangeably with any other implementation. The client doesn't care what other methods the implementor has, it is only interested in using the interface methods.
But code that is not acting as a client of the interface may view the implementation in a completely different way. Some other piece of code may construct a new SpaceShip and call getSpaceEquipment(). That's also normal. If you construct a new Truck then you can't call getSpaceEquipment() because that class does not have that method.
It would be a mistake to add methods like getSpaceEquipment() to the interface that Truck and SpaceShip both implement, say Vehicle. getSpaceEquipment() only makes sense for a SpaceShip not for all Vehicles.
You could create an extension of Vehicle called SpaceVehicle and declare the getSpaceEquipment() method in it. Then SpaceShip could implement SpaceVehicle (which makes it also a Vehicle by inheritance). But you would only do that if you were going to have several implementors of SpaceVehicle and you needed to write code that works with SpaceVehicle instances but does not care whether the SpaceVehicle is a SpaceShip or a Satelite or whatever.

Can we have two or more classes in a Laravel controller

Considering Interface Segregation Principle, which is one among the most “talked about” principles of Object Oriented Programming - SOLID principles, I was wondering if it were possible to have two different classes in a single Laravel controller? For example:
<?php
namespace ...;
use App\Http\Controllers\Controller;
interface VehicleInterface
{
public function ...
}
class CarController extends Controller implements VehicleInterface
{
...
}
class ElectricCar implements VehicleInterface
{
...
}
Technically you can have multiple classes in the same file.
With Laravel (or any framework), not really, if you want to use its autoloader, as classname = filename is the convention.
Also, a controller is what handles requests. You can load as many instances of your different classes inside a controller function. But defining other classes inside the controller file is not what you're supposed to do, at all.
This question has at least two problems:
I do not think that ElectricCar and CarController should share the same interface. The ElectricCar models a car, possibly with methods like accelerateTo(120mph) whereas the CarController maybe has methods like accelerateCarTo(Car5, 120mph). They are also used with a different meaning: The ElectricCar models one single car, whereas the CarController manages access to a single or multiple cars, which is also called from a abstract construct modeling an application flow.
The interface segregation principle does not speak about classes, so the question is ill-formed in the first place. The interface segregation principle says that one interface(!) specifying multiple use cases should be broken up into multiple interfaces(!) called role interfaces, each fulfilling exactly one use case. For example, an interface modeling an ATM with methods like deposit() and withdraw() should be split up into two interfaces each only fulfilling one of these functions. The goal is that a dependent entity must only use and see the parts it really requires.

Scenarios for using Abstract Class and Interface Class

I know the concepts of Abstract Class and Interface Class.
But I want real time example which explains both the concept in our design.
Can anyone help with this?
Both have little different scenerios...
Abstract classes also contains method definition as you know interface does not. But if you defines abstract class you can not inherit more than one classes from child class. But In case of interface you can do that and implement the methods declared inside the interface.
These scenerios are used in the software development as we just declared the signature of the method and then user can write his.her own code inside the method by overriding it.
Here I am mentioning some point what we can do with abstract class and interface
In abstract class you can define abstract methods which should be public or protected. but in Interface you can define public abstract method only.
In abstract class you can define data members and constants but in interface you can define constants only.
In abstract class you can define body of method and you can inherit in sub class, but in interface you can not define body of method.
you can implement multiple interface in a sub class, but you can not inherit multiple abstract classes in a sub class.
Example
In Major Frameworks, uses interfaces for different types of data source class. If we want to make data source class for new introduced database then we must have to implement their interface in our class so it make well maintained code and methods parameters.

Limit which classes can call another class by namespace or interface

Is it possible to programmatically limit access to a class methods from another class?
I am working with an MVC framework which is made up of modules. Modules exist in their own namespace and namespace exactly mimics folder structure. A module contains, at least, a class that is an instance of the module interface but usually a controller and a model. Most of them also contain lib classes unique to that module.
For what we need this is quite a sweet setup. A module obviously needs to access the public methods of its own namespaced classes but that means other modules can do that too and they should only be calling the module class public methods.
Can a class method's scope be limited to a single namespace (or by interface) or is this a step too much for PHP's current level of object oriented implementation?

Improving class structure in PHP instead of using multiple inheritance

I have a design problem where my classes are set up in such a way:
abstract class Advertiser abstract class AdvertiserCampaign
| |
| |
class AdvUno extends Advertiser class AdvUnoCampaign extends AdvertiserCampaign
class AdvDos extends Advertiser class AdvDosCampaign extends AdvertiserCampaign
class AdvTre extends Advertiser class AdvTreCampaign extends AdvertiserCampaign
The problem is that AdvUno and AdvUnoCampaign both need a special authentication method that's not necessary for the others. Right now I've placed it in AdvUno, but again, it'll be needed by AdvUnoCampaign (and a bunch of other classes that are set up in this way).
I can't make AdvUnoCampaign extend AdvUno since there's no multiple inheritance in PHP, but also because it's just generally not a good, clean design practice.
If I make AdvertiserCampaign extend Advertiser, then all of the extending classes below (AdvUnoCampaign, AdvDosCampaign, etc) must implement a bunch of abstract methods that are of no concern to them, and which are already implemented in each of the Advertiser classes.
In short, what's the best design practice in this sort of situation? I'd rather not just copy and paste the code into all of the AdvOne classes. Any help or advice would be appreciated. Thanks!
Parallel Inheritance Hierarchies are considered a code smell, something that should be refactored.
Martin Fowler suggests in "Refactoring":
The general strategy for eliminating the duplication is to make sure that instances of one
hierarchy refer to instances of the other. If you use Move Method and Move Field, the hierarchy
on the referring class disappears.
But I think you can go one step further. I don't know, what your decision was based on to make sub classes for each advertiser and their campaigns, but I would challenge this decision. A good practise to follow is to Favor Composition over Inheritance.
You could start like that:
class Advertiser
{
protected $authentication;
}
class AdvertiserCampaign
{
protected $authentication;
}
interface AdvertiserAuthentication
{
}
class SpecialAuthenticationForAdvertiserUno implements AdvertiserAuthentication
{
}
class NoSpecialAuthenticationForOtherAdvertisers implements AdvertiserAuthentication
{
}
Now the first difference between the advertisers is moved into another class. Go on with other differences until each advertiser is just an object of Advertiser composed in a different way. The same goes for the campaigns. I would like to be more concrete but as stated before, I have no idea why your advertisers all have their own classes in the first place.
In general, to resolve problems similar to yours the Bridge design pattern is commonly used.
http://sourcemaking.com/design_patterns/bridge

Categories