Skip to content

Commit 2a5a82e

Browse files
committed
php 8.3
1 parent 406f4c0 commit 2a5a82e

File tree

5 files changed

+57
-61
lines changed

5 files changed

+57
-61
lines changed

Diff for: architecture/design-patterns.md

+12-8
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ class TruckArrival implements IArrival
1717
{
1818
public function getProducts(): array
1919
{
20-
...
20+
# some logic
2121
}
2222
}
2323

2424
class ShipArrival implements IArrival
2525
{
2626
public function getProducts(): array
2727
{
28-
...
28+
# some logic
2929
}
3030
}
3131

@@ -36,20 +36,24 @@ class StockControl
3636

3737
private function getArrival(int $arrivalType): IArrival
3838
{
39+
$arrival = null;
3940
if ($arrivalType === self::TRUCK_ARRIVAL) {
40-
return new TruckArrival();
41-
}
42-
if ($arrivalType === self::SHIP_ARRIVAL) {
43-
return new ShipArrival();
41+
$arrival = new TruckArrival();
42+
} elseif ($arrivalType === self::SHIP_ARRIVAL) {
43+
$arrival = new ShipArrival();
44+
} else {
45+
throw new \Exception("{$arrivalType} don`t exist");
4446
}
47+
48+
return $arrival;
4549
}
4650

4751
public function control()
4852
{
49-
...
53+
# some logic
5054
$arrival = $this->getArrival($arrivalType);
5155
$products = $arrival->getProducts();
52-
...
56+
# some logic
5357
}
5458
}
5559
```

Diff for: architecture/grasp.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class Bill {
8181
foreach($this->billProducts as $billProduct) {
8282
$totalSum += $billProduct->getSum();
8383
}
84-
...
84+
# some logic
8585
}
8686
}
8787
```

Diff for: architecture/oop.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ class FoodBill implements IBill
1616
{
1717
public function getSum(): float
1818
{
19-
...
19+
# some logic
2020
}
2121
}
2222

2323
class DrinkBill implements IBill
2424
{
2525
public function getSum(): float
2626
{
27-
...
27+
# some logic
2828
}
2929
}
3030

@@ -43,7 +43,7 @@ class FullBill
4343
foreach($this->bills as $bill) {
4444
$sum += $bill->getSum();
4545
}
46-
...
46+
# some logic
4747
}
4848
}
4949
```

Diff for: architecture/solid.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class Bill implements FileContract
1414
{
1515
public function getDocumentBody(): string
1616
{
17-
...
17+
# some logic
1818
return "Bill sum";
1919
}
2020
}
@@ -23,7 +23,7 @@ class Report implements FileContract
2323
{
2424
public function getDocumentBody(): string
2525
{
26-
...
26+
# some logic
2727
return "Report data";
2828
}
2929
}

Diff for: readme.md

+39-47
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
## PHP Guidelines
1+
# PHP Guidelines
22

3-
### Introduction
3+
An example of the concept can be found at the link: [PHP Guidelines example](https://github.com/pvaviloff/php-guidelines-example)
4+
5+
## Introduction
46

57
This document provides a set of strategies/recommendations for scaling up development teams and structuring projects. To achieve team scalability, there are two goals that drive the process: writing code as if it was developed by a single developer, and writing documentation that can be understood by someone off the street.
68

@@ -14,7 +16,7 @@ People work on the project, and there is a risk of encountering misunderstanding
1416

1517
The team is not homogeneous. The end of the implementation process can be considered when 80% of the team follows the established process. The introduction of new technology generates/changes/imposes restrictions on the work process. Before implementation, an analysis of the team's readiness is required.
1618

17-
### Basic concepts and logic for applying theoretical knowledge
19+
## Basic concepts and logic for applying theoretical knowledge
1820

1921
- How to write code? Basic approaches to coding.
2022
- [Functional programming](./architecture/functional-programming.md)
@@ -24,7 +26,7 @@ The team is not homogeneous. The end of the implementation process can be consid
2426
- [SOLID](./architecture/solid.md)
2527
- [Design patterns](./architecture/design-patterns.md)
2628

27-
### Preamble
29+
## Preamble
2830
The main goal of the team is to solve business process-related problems promptly. Therefore, all code should be written according to [PSR-4](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md) and [Clean Code](https://github.com/piotrplenik/clean-code-php). If you are not sure whether you are writing readable code, consult your neighbor. It does not have to be someone from the team. We follow the rule: "If two people understood what was written, the third is likely to understand it too."
2931

3032
The first problems start with implicitly described tasks and poorly designed base. If you have any questions while reading the task, first of all, write them in the task comment and ask the PM. There are often situations where you discuss the clarification of the task directly with the task assigner. If this happens, make it a rule to notify the PM of any changes/clarifications. Ask the task assigner to adjust the task or even just send the correspondence in which you resolved the unclear points to the task. All clarifications and/or changes to the task must be recorded in the task. This can lead to a task re-estimation.
@@ -39,7 +41,7 @@ Do we need to write documentation? Documentation is only necessary for functiona
3941

4042
Documentation should consist of two blocks. You describe the technical documentation. Also, through the PM, ask the product owner to describe the user documentation, which should describe: why the functionality was created, how to use it (preferably with screenshots) from the user's point of view (UX). You need to describe how it should work, and the product owner should describe how to work with it.
4143

42-
#### Used concepts
44+
### Used concepts
4345

4446
The team aims to write as one developer. What does it mean? Empirically identified principles and recommendations have been developed that work within the overall system and allow the entire team to write in one style. The basis is taken from the Symfony documentation, SOLID, and DDD.
4547

@@ -53,9 +55,11 @@ The programmer should act as a translator from the language of the project manag
5355

5456
We also adhere to the principle of a "layered cake." We delimit responsibility zones and link each zone using dependency injection (DI).
5557

56-
![onion](./images/onion.png)
58+
<p align="center">
59+
<img src="./images/onion.png" />
60+
</p>
5761

58-
#### Used from SOLID:
62+
### Used from SOLID:
5963

6064
The Single Responsibility Principle states that a service should have only one responsibility. It is easily implemented in our conditions, both during refactoring and when developing new functionality.
6165

@@ -65,13 +69,13 @@ The Interface Segregation Principle suggests that it is better to have many inte
6569

6670
The Liskov Substitution Principle states that if S is a subtype of T, then objects of type T can be replaced with objects of type S without any desired properties being changed. It is partially achievable and depends on implementation.
6771

68-
#### Not used from SOLID:
72+
### Not used from SOLID:
6973

7074
The Open Closed Principle A class should be open for extension but closed for modification. The biggest problem is that not everyone from other teams may follow the SOLID principles. In projects with 10+ people, it is difficult to maintain versioning of objects.
7175

7276
We use Dependency Injection to remove dependencies between Controllers, Services, and Repositories and to reduce code coupling.
7377

74-
### General implementation scheme
78+
## General implementation scheme
7579

7680
Based on MVC, we build a basic architecture:
7781

@@ -81,8 +85,6 @@ Repository - a class that manages data storage (MySQL, MongoDB, ClickHouse). We
8185

8286
Entity - a class that describes the structure of databases.
8387

84-
Transformer - a class that transforms the final result for further transmission. Place it next to the service for which it is intended.
85-
8688
To link the Controller, Service, and Repository together, we use a Value Object. The Value Object also combines the concept of DTO to reduce the number of entities. Often, DTOs when changing business logic often merge into Value Objects.
8789

8890
## General Interaction Scheme
@@ -100,7 +102,7 @@ In Controllers that implement business logic from Domains, it is prohibited to u
100102
The use of traits is prohibited in projects.
101103
Direct access to the container is prohibited (with the exception of service providers and factories).
102104

103-
#### Project structure
105+
## Project structure
104106

105107
---- src/
106108
---- ---- ExampleDomain/
@@ -110,57 +112,46 @@ Direct access to the container is prohibited (with the exception of service prov
110112
---- ---- ---- [Exceptions/](#exceptions)
111113
---- ---- ---- [Repositories/](#repository)
112114
---- ---- ---- [Services/](#services)
113-
---- ---- ---- [ValueObjects/](#dto-и-valueobject)
115+
---- ---- ---- [ValueObjects/](#dto-and-valueobject)
114116
---- ---- ExampleInfrastructure/
115117
---- ---- ---- Commands/
116118
---- ---- ---- Controllers/
117-
---- ---- ---- EventListeners/
119+
---- ---- ---- MessageHandlers/
118120
---- ---- ---- Requests/
119121
---- ---- ---- Responses/
120122

121-
### Entity
123+
## Entity
122124

123125
Entity - defines a certain entity in the business logic and always has an identifier (a unique key. The key can be expressed as an id/guid/uuid or a combination of properties (a composite unique key) that will identify the entity), by which the Entity can be found or compared to another Entity. If two Entities have identical identifiers, they are the same Entity. It is almost always mutable.
124126

125127
```php
126128
<?php
129+
127130
namespace App\BrandDomain\Entities;
128131

129-
use Doctrine\ORM\Mapping\Entity;
130-
use Doctrine\ORM\Mapping\Table;
131132
use Symfony\Component\Uid\Uuid;
132133
use Doctrine\ORM\Mapping as ORM;
133-
use Doctrine\ORM\Mapping\UniqueConstraint;
134134

135-
/**
136-
* @Entity
137-
* @Table(name="brands")
138-
*/
135+
136+
#[ORM\Entity]
137+
#[ORM\Table(name:"brands")]
139138
class BrandEntity
140139
{
141-
/**
142-
* @ORM\Id()
143-
* @ORM\Column(type="uuid")
144-
*/
145-
private Uuid $guid;
140+
#[ORM\Id]
141+
#[ORM\Column(type: "uuid")]
142+
public readonly Uuid $guid;
146143

147144
public function __construct(
148-
/**
149-
* @ORM\Column(length: 140)
150-
*/
151-
private readonly int $name,
145+
#[ORM\Column(length: 140)]
146+
public readonly string $name,
152147
) {
153148
$this->guid = Uuid::v4();
154149
}
155150

156-
public function getGuid(): Uuid
157-
{
158-
return $this->guid;
159-
}
160151
}
161152
```
162153

163-
### DTO and ValueObject
154+
## DTO and ValueObject
164155

165156
Data Transfer Object (DTO) - is an object, a data structure that carries information between processes (Controllers, Services, Repositories). It is desirable not to change already set properties to get rid of implicit logic. It has no dependencies. It only contains typed properties and getters/setters. No logical actions can be performed in this object. It is often used to pass filters from the controller to services and repositories.
166157

@@ -179,7 +170,7 @@ final class BrandCreatorObject
179170
}
180171
```
181172

182-
### Aggregates
173+
## Aggregates
183174

184175
Aggregate - the use of aggregates allows avoiding excessive connection between objects that make up the model. This avoids confusion and simplifies the structure by not allowing the creation of tightly coupled systems.
185176

@@ -201,7 +192,7 @@ final class BrandCreatorAggregate
201192
}
202193
```
203194

204-
### Constants
195+
## Constants
205196

206197
Constant - is a regular class with constants. Everyone always encounters regular expressions, status IDs, etc. Now, all constants are moved to separate classes for reuse.
207198

@@ -215,7 +206,7 @@ final class DbConst
215206
}
216207
```
217208

218-
### Exceptions
209+
## Exceptions
219210

220211
Exceptions - stores named errors. Do not throw the default exception if you need to throw an error - throw a custom error. They should be used and necessary everywhere in Repositories, Services, etc.
221212
```php
@@ -227,11 +218,11 @@ final class BrandCreatorException extends \Exception
227218
}
228219
```
229220

230-
### Dependency injection
221+
## Dependency injection
231222

232223
Dependency injection (DI) is a style of object configuration where an object's fields are set by an external entity. In other words, objects are configured by external objects. DI is an alternative to self-configuration of objects.
233224

234-
### Repository
225+
## Repository
235226

236227
Repository - these are classes that represent collections of objects. They do not describe storage in databases, caching, or the solution of any other technical problem. Repositories represent collections. How we store these collections is simply an implementation detail. In repositories, we write all queries to databases such as MySQL, MongoDB, ClickHouse, etc. We do not implement methods for deleting/editing/creating entities in repositories. We use UnitOfWork for this.
237228
```php
@@ -247,7 +238,7 @@ use Symfony\Component\Uid\Uuid;
247238
final class BrandRepository
248239
{
249240
public function __construct(
250-
private Connection $connection;
241+
private Connection $connection,
251242
) {
252243
}
253244

@@ -278,11 +269,12 @@ final class BrandRepository
278269
'name',
279270
])
280271
->from(DbConst::BRANDS);
281-
...
272+
# some logic
273+
282274
foreach ($query->executeQuery()->iterateAssociative() as $brand) {
283275

284276
yield new BrandObject(
285-
Uuid::fromString(brand['guid']),
277+
Uuid::fromString($brand['guid']),
286278
$brand['name'],
287279
);
288280
}
@@ -304,11 +296,11 @@ final class BrandRepository
304296
}
305297
```
306298

307-
### UnitOfWork
299+
## UnitOfWork
308300

309301
UnitOfWork - [pattern](https://martinfowler.com/eaaCatalog/unitOfWork.html) is used in Service to save/edit/delete all entities within a single transaction. An example of implementation is [Entity Manager in Doctrine](https://symfony.com/doc/current/doctrine.html).
310302

311-
### Services
303+
## Services
312304

313305
Service - is a class or classes that implement business logic and interact with entities. The implementation of the service depends on the use cases. Services can implement their own architecture, implement patterns, and use additional entities created within the service. Upon exiting the service, we still obtain the entities described here: Entity/Aggregate/ValueObject.
314306
```php
@@ -347,7 +339,7 @@ final class BrandCreator
347339
}
348340
```
349341

350-
### Collections
342+
## Collections
351343

352344
We recommend using the implementation [https://github.com/ramsey/collection](https://github.com/ramsey/collection) as they are typed. If possible, avoid using arrays.
353345

0 commit comments

Comments
 (0)