Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use protected over private when it's possible #15396

Closed
mehdi-ghezal opened this issue Sep 4, 2019 · 12 comments
Closed

Use protected over private when it's possible #15396

mehdi-ghezal opened this issue Sep 4, 2019 · 12 comments
Labels
CO Category: Core Improvement Type: Improvement No change required Resolution: issue closed because expected as is

Comments

@mehdi-ghezal
Copy link
Contributor

Is your feature request related to a problem? Please describe.

I try to extends CartPresenter in a custom module but I cannot access property like $priceFormatter, $link, etc... because theses properties has been declare as private property.

What the purpose of private over protected in this use case ?

IMHO, it only make harder to extends Prestashop and less developer friendly.

Describe the solution you'd like

Use protected over private when it's not REQUIRED to hide property from derived class.
This recommandation can be extend in the whole project as I don't think it's only related to this class.

Describe alternatives you've considered

No alternative solution, just a workaround ; I recreate the required objects for my business logic but it's a non sense as they already exists in parent class.

Additional context

None.

@khouloudbelguith
Copy link
Contributor

Hi @mehdi-ghezal,

Thanks for your report.
Ping @PrestaShop/prestashop-core-developers what do you think?
Similar issue reported on Forge: http://forge.prestashop.com/browse/BOOM-2376

Thanks!

@khouloudbelguith khouloudbelguith added CO Category: Core Improvement Type: Improvement Waiting for dev Status: action required, waiting for tech feedback labels Sep 4, 2019
@mehdi-ghezal
Copy link
Contributor Author

BTW, same suggestion for methods.

@matks
Copy link
Contributor

matks commented Sep 4, 2019

Hi @mehdi-ghezal about the answer whether to use private or protected functions/properties, the answer is probably "yes and no"

When we add new code into PrestaShop codebase, we ask ourselves the question "How should I allow PrestaShop developers to extend/customize this behavior while avoiding complex side-effects (which leads to bugs) or corrupted data state ?"

For example consider this code:

class ImageFinder
{
	private $folderPath;

	public function __construct($folderPath)
	{
		$this->folderPath = $folderPath;
	}

	public function getImageByName($imageName)
	{
		return file_get_contents($folderPath.'/'.$imageName);
	}
}

By setting this property "folderPath" in private we "lock" the class behavior and consequently we are sure the property "folderPath" CANNOT be changed between the call of __construct and the call of getImageByName. If we do not lock it, some people could do a mistake and modify the "folderPath" which could bring the following behavior:

  • you call "__construct" with the right folder path => everything is cool
  • some 3rd party code (maybe a module that you have installed in the shop ?) modifies the folder path
  • you call getImageByName and it's broken because the folder is wrong !

Do you see what I mean ? This bug would be very hard for you to analyze because the data was changed at some point by a 3rd party code that you might not even know it's there.

This is the main reason why we put functions and properties in private. We think "this is an internal setting needed to ensure the correct behavior of this piece of code, better lock it".

In order to allow developers to extend/customize the behavior we provide protected properties and functions, public properties and functions, extension mechanisms (hooks and overrides).

But we are not always right . So YES sometimes we do a mistake and lock some setting/function that needs to be accessible from the outside as it unlocks a key customization behavior. But sometimes NO we prefer not to let this go wild as messing with some key pieces of PrestaShop can put you in a very complicated situation.

Every software/platform/library that has customization capabilities has to ask itself this complex question 😅 "should it be locked or not ?" . For example https://github.com/symfony/symfony is obviously a framework that allows extension/customization and they also have private, protected and public functions and properties 😉

To sum up

If you have some usecases where you wanted to do something with PrestaShop and you could not because of a private property/function, please tell us by opening a github issues 😉 (or even creating the Pull Request to make it available ?) we'll consider the change and if it is relevant we'll change it for the next version. But sometimes we'll keep some things locked as we are afraid of the dangerous mistakes their usage can bring.

@khouloudbelguith khouloudbelguith added Waiting for author Status: action required, waiting for author feedback and removed Waiting for dev Status: action required, waiting for tech feedback labels Sep 4, 2019
@mehdi-ghezal
Copy link
Contributor Author

Hello,

I get it about the encapsulation principle and the idea about ensure that the object behave as excepted ; but let me give you an example : CartPresenter.php

This class is used different place such as CartController. There is no possibilities to override it globally (and override is bad !!). So it mean, the CartController will ALWAYS use the CartPresenter define in Prestashop namespace.

If you look about this class, almost everything is private, so in my module I want to reuse this class by extend it ; but I cannot access the property such as $priceFormatter. I have to create a new instance of PriceFormatter ; same problem with methods.

So, this class has been locked with no apparent reason as :

  1. We cannot override it globally (AFAIK)
  2. It's use explicitly in controller (cannot change the class by an IoC mechanism for example)

In this suggestion, I talk about inheritance and not overriding, it's not the first time I get this kind of problem and it's not in legacy code but new one. It's why I made this suggestion.

One last thing, I understand that you trying to protect the core from wrong modules or poor development but with too much restriction people will just :

  • Edit the core file to change (ouch...)
  • Copy / Paste the complete code that could be easily break in a future upgrade

I know, there is no magic solution and not one single answer, but when I look the CartPresenter class I cannot hold myself to think about a big black box where everything has been put in private without a real thinking.

Regards,

@khouloudbelguith khouloudbelguith added Waiting for dev Status: action required, waiting for tech feedback and removed Waiting for author Status: action required, waiting for author feedback labels Sep 4, 2019
@matks
Copy link
Contributor

matks commented Sep 26, 2019

@mehdi-ghezal About the Cart Presenter:

Unfortunately the people who built it are no longer working on the project, so we will not have the answers for sure, however my guess would be this:

By "locking" the Cart Presenter, you provide one guarantee for 3rd-party themes: "we guarantee the following list of variables will always be available for you to use in your Smarty templates". That's the only relevant reason I can think of. If we allow people to modify its behavior, then it means 3rd-party theme might not work on a modified shop as the required variable might not be available.

This put aside, your comment is right:

This class is used different place such as CartController. There is no possibilities to override it globally (and override is bad !!). So it mean, the CartController will ALWAYS use the CartPresenter define in Prestashop namespace.

So would the following changes address your need ?

  • allow dependency injection on CartPresenter in order to allow you to use another PriceFormatter
  • allow dependency injection on CartController in order to allow you to use another CartPresenter

I think it would make sense, and dependency injection is a proper way to perform the wanted behavior.

@khouloudbelguith khouloudbelguith added Waiting for author Status: action required, waiting for author feedback and removed Waiting for dev Status: action required, waiting for tech feedback labels Sep 26, 2019
@khouloudbelguith
Copy link
Contributor

Hi @mehdi-ghezal,

Since we had no news from you for more than 30 days, I'll close this ticket. Feel free to open another one if you can give specific details.

Thanks!

@khouloudbelguith khouloudbelguith added No change required Resolution: issue closed because expected as is and removed Waiting for author Status: action required, waiting for author feedback labels Oct 29, 2019
@jf-viguier
Copy link
Contributor

@mehdi-ghezal is right about the Cart Presenter : we can't change it it's a main issue. Why closing it @khouloudbelguith ?

@jf-viguier
Copy link
Contributor

Presenter should at list have hooks :
#11125

@ghost
Copy link

ghost commented Jan 13, 2020

Bump !

@khouloudbelguith
Copy link
Contributor

Hi @jf-viguier,

About closing the issue after 30 days with no response, we just discussed in this subject & it will be an update of those rules described in this issue: PrestaShop/prestashop-retro#54
In the meantime, I will re-open this issue.

is right about the Cart Presenter: we can't change it it's a main issue.

Ping @PrestaShop/prestashop-core-developers what do you think?

Thanks!

@khouloudbelguith khouloudbelguith added Waiting for dev Status: action required, waiting for tech feedback and removed No change required Resolution: issue closed because expected as is labels Jan 15, 2020
@PierreRambaud
Copy link
Contributor

Since #11125 has been merged, we don't have to use protected instead of private right now.
Feel free to reopen if you think it's really mandatory.

@hibatallahAouadni hibatallahAouadni removed the Waiting for dev Status: action required, waiting for tech feedback label Jan 18, 2021
@hibatallahAouadni hibatallahAouadni added the No change required Resolution: issue closed because expected as is label Jan 18, 2021
@mehdi-ghezal
Copy link
Contributor Author

As I encounter again the same issue in another context, let me explain another use case where private variable are blocking. Le't say I have a core class from Prestashop that do an amazing job about formatting a product. I want to reuse it in my module but adding extra feature for my module.

So I am gonna extend it and use my classe that inherit the core feature ; except that I cannot use all the private property and method. After we can debate for days when to use private, when to use protected.

You can certainly try to maintain the integrity of a Prestashop instance instance by over using private methods and attributes but it's an illusion as end user have many other ways to compromise the integrity of his instance.

Ultimately, it's an eCommerce platform, not a blogging system, it is supposed to generate revenue end user are responsible of what extra code (by module, theme or other) they bring to their system.

Anyway just some food for thought.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CO Category: Core Improvement Type: Improvement No change required Resolution: issue closed because expected as is
Projects
None yet
Development

No branches or pull requests

6 participants