Comments (8)
@mxr576, have you ever had to deal with this--a class autoloader needing to know about your internal/infrastructure layer, and by extension, external client projects depending on it?
from composer-stager.
Thanks for the ping, I am definitely interested. I'll try to understand the problem and share my 2 cents.
from composer-stager.
My first impression after 3 minutes: am I missing the application/use case layer in PhpTuf\ComposerStager
that would contain classes with explicit use case implementations?
Like \PhpTuf\ComposerStager\API\Core\CleanerInterface
is an API... but the only available implementation is internal at \PhpTuf\ComposerStager\Internal\Core\Cleaner
.
The same for \PhpTuf\ComposerStager\Internal\Core\Beginner
which is used why DIC by \PhpTuf\ComposerStagerConsole\Console\Command\BeginCommand
.
IMO, use cases should be public, part of the API and BC promise in a library like ComposerStager; those are executed via presentation layer codes, like this console command.
from composer-stager.
Thanks, @mxr576. As an API-only library, Composer Stager is application agnostic--like Symfony components, for example. Drupal Automatic Updates is the canonical application, and Composer Stager Console is another.
Are you suggesting that the internal core classes (\PhpTuf\ComposerStager\Internal\Core
) are effectively use cases that should be in their own separate, public layer instead? If so, how do you protect external applications from implementation changes in them? And wouldn't that just shift the problem? In other words, if a use case class needs to use PhpTuf\ComposerStager\API\FileSyncer\Service\FileSyncerInterface
(API), wouldn't the autoloader still need to know about PhpTuf\ComposerStager\Internal\FileSyncer\Factory\FileSyncerFactory
(internal)?
from composer-stager.
Still scratching the surface of the code... so consider that when you read my answer.
Composer Stager is application agnostic--like Symfony components
👍 If Symfony would not be in a sentence and would only appear as optional dependencies, it would be even cooler. But sometimes, based on costs & benefits, relying on external components is the better choice.
I found it extremely strange that the only public components of ComposerStager under PhpTuf\ComposerStager\API
are interfaces and exception classes. What are the benefits of a library that only has opinions without actual solutions?
Are you suggesting that the internal core classes (
\PhpTuf\ComposerStager\Internal\Core
) are effective use cases that should be in their own separate, public layer instead?
Probably yes, and even more... What is the risk being marking \PhpTuf\ComposerStager\Internal\FileSyncer\Service\PhpFileSyncer
or PhpTuf\ComposerStager\Internal\FileSyncer\Factory\FileSyncerFactory
or \PhpTuf\ComposerStager\Internal\Process\Service\Process
(or at least the related factory \PhpTuf\ComposerStager\Internal\Process\Factory\ProcessFactory
) as part of the public API? They are implementations of well-defined contracts that constrain them and they are also covered by tests.
If so, how do you protect external applications from implementation changes in them?
Since contracts (interfaces) describe the expected behaviors, dependent codes should not/must not care about implementation changes until those remain compatible with the contract. If there were serious oversight in designing a contract and related implementations, then changing the contract will create a new major version and that is fine; that is the expected way of software evolution.
In the case of use cases, they can only change in a BC way, or else a new use case needs to be defined that may replace the existing one in a new major version. There could be multiple use cases provided by a library for a problem in the same problem space. Like a synchronous and asynchronous use case implementation for compiling SCSS files...
And wouldn't that just shift the problem? In other words, if a use case class needs to use PhpTuf\ComposerStager\API\FileSyncer\Service\FileSyncerInterface (API), wouldn't the autoloader still need to know about PhpTuf\ComposerStager\Internal\FileSyncer\Factory\FileSyncerFactory (internal)?
So one part, ComposerStager
can provide already identified use cases as part of its public APIs with implementations for use case implementations. Because their dependencies also become part of the public API (and they usually implement a contract, right?), so if it becomes necessary, then consumers of the library can also put together their own use cases and rely on interfaces from this library and valuable implementations for those.
from composer-stager.
Thanks for your input, @mxr576! I'll have to give it some thought. In the meantime, I was able to solve the particular problem in this issue (PR above) without significant redesign.
from composer-stager.
@TravisCarden I am glad it got resolved quickly and thanks for the ping! I hope you did not regret based on my feedback, I hope I was not harsh. This is an interesting and high quality project, I like getting back to it time after time.
This thread and the fix for the problem also proved my assumption that I am I've been cherishing for a long time: Without a DIC or a service locator that can bypass layering rules, it is really complicated or kinda impossible to keep them implemented by the book. Something MUST initiate objects and inject them in the place of contract dependencies.
from composer-stager.
I hope you did not regret based on my feedback, I hope I was not harsh.
I always appreciate your feedback, @mxr576, and I didn't take you to be harsh at all. 🙂
This is an interesting and high quality project, I like getting back to it time after time.
Thank you! 😄
Without a DIC or a service locator that can bypass layering rules, it is really complicated or kinda impossible to keep them implemented by the book.
My experience on this project has led me to the same conclusion. That's why it's the only approach that's officially supported. That leaves me with complete freedom to do even major refactoring in the Internal layer without breaking contracts. As long as I depend exclusively on interfaces, anyone could replace my implementations or decorate them, but since they can't subclass them, they can't depend directly on any implementation details.
from composer-stager.
Related Issues (20)
- Get code review from Core maintainers.
- Evaluate the rector/rector dev dependency
- Evaluate the infection/infection dev dependency
- Create an issue template for security reports
- Create a governance policy
- Idea: create another repo/package with OS-specific syncers HOT 1
- Support having the active and staging directories on different drives on Windows
- Fix confusion of responsibilities between `Internal\Path\Value\Path` and `Internal\Helper\PathHelper`
- Write tests for custom test assertions in `Tests\TestUtils\AssertTrait`
- Prohibit using root directories on Windows
- Add tests that the file syncer preserves file permissions
- Support having the active and staging directories nested on Windows
- Allow symlinks on Windows
- Add precondition that active and staging directories have a common root
- Use the Composer process runner internally when running Composer commands HOT 2
- Ensure PHP 8.3 compatibility HOT 1
- Make compatible with Symfony 7 to support Drupal core 11.x HOT 2
- Add support for PHAR executables HOT 1
- Add incremental output getters to `API\Process\Service\OutputCallbackInterface`?
- Pass `--checksum` to rsync HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from composer-stager.