Skip to content

Commit

Permalink
Drop Flyweight pattern
Browse files Browse the repository at this point in the history
There is a growing need for types with parameters, and that pattern was
probably used out of concerns that are no longer relevant anyway.
  • Loading branch information
greg0ire committed Feb 5, 2022
1 parent 83766f9 commit 96c2ebf
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 91 deletions.
38 changes: 38 additions & 0 deletions docs/en/reference/types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -905,3 +905,41 @@ hook it into the database platform:
This would allow using a money type in the ORM for example and
have Doctrine automatically convert it back and forth to the
database.

It is also possible to register type instances directly, in case you
need to pass parameters to your instance::

<?php
namespace My\Project\Types;

use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;

final class StringReplacingType extends StringType
{
/**
* @param array<string, string> $replacements
*/
public function __construct(
private array $replacements,
) {
}

public function convertToDatabaseValue($value, AbstractPlatform $platform): string
{
return strtr($value, $this->replacements);
}
}

To do that, you can obtain the ``TypeRegistry`` singleton from ``Type``
and register your type in it::

<?php
Type::getTypeRegistry()->register('emojifyingType', new StringReplacingType(
[
':)' => '😊',
':(' => '😞',
':D' => '😄',
':P' => '😛',
]
));
27 changes: 0 additions & 27 deletions src/Types/Exception/TypeAlreadyRegistered.php

This file was deleted.

1 change: 0 additions & 1 deletion src/Types/Type.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ private static function createTypeRegistry(): TypeRegistry

/**
* Factory method to create type instances.
* Type instances are implemented as flyweights.
*
* @param string $name The name of the type.
*
Expand Down
28 changes: 3 additions & 25 deletions src/Types/TypeRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,20 @@
namespace Doctrine\DBAL\Types;

use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Types\Exception\TypeAlreadyRegistered;
use Doctrine\DBAL\Types\Exception\TypeNotFound;
use Doctrine\DBAL\Types\Exception\TypeNotRegistered;
use Doctrine\DBAL\Types\Exception\TypesAlreadyExists;
use Doctrine\DBAL\Types\Exception\UnknownColumnType;

use function array_search;
use function in_array;

/**
* The type registry is responsible for holding a map of all known DBAL types.
* The types are stored using the flyweight pattern so that one type only exists as exactly one instance.
*/
final class TypeRegistry
{
/**
* Map of type names and their corresponding flyweight objects.
* Map of type names and their corresponding objects.
*
* @var array<string, Type>
*/
Expand Down Expand Up @@ -56,9 +53,9 @@ public function get(string $name): Type
*/
public function lookupName(Type $type): string
{
$name = $this->findTypeName($type);
$name = array_search($type, $this->instances, true);

if ($name === null) {
if ($name === false) {
throw TypeNotRegistered::new($type);
}

Expand All @@ -84,10 +81,6 @@ public function register(string $name, Type $type): void
throw TypesAlreadyExists::new($name);
}

if ($this->findTypeName($type) !== null) {
throw TypeAlreadyRegistered::new($type);
}

$this->instances[$name] = $type;
}

Expand All @@ -102,10 +95,6 @@ public function override(string $name, Type $type): void
throw TypeNotFound::new($name);
}

if (! in_array($this->findTypeName($type), [$name, null], true)) {
throw TypeAlreadyRegistered::new($type);
}

$this->instances[$name] = $type;
}

Expand All @@ -120,15 +109,4 @@ public function getMap(): array
{
return $this->instances;
}

private function findTypeName(Type $type): ?string
{
$name = array_search($type, $this->instances, true);

if ($name === false) {
return null;
}

return $name;
}
}
22 changes: 0 additions & 22 deletions tests/Types/Exception/TypeAlreadyRegisteredTest.php

This file was deleted.

23 changes: 7 additions & 16 deletions tests/Types/TypeRegistryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public function testRegister(): void
self::assertSame($newType, $this->registry->get('some'));
}

public function testRegisterWithAlradyRegisteredName(): void
public function testRegisterWithAlreadyRegisteredName(): void
{
$this->registry->register('some', new TextType());

Expand All @@ -96,10 +96,12 @@ public function testRegisterWithAlreadyRegisteredInstance(): void
{
$newType = new TextType();

$this->registry->register('some', $newType);

$this->expectException(Exception::class);
$this->registry->register('other', $newType);
$this->registry->register('type1', $newType);
$this->registry->register('type2', $newType);
self::assertSame(
$this->registry->get('type1'),
$this->registry->get('type2')
);
}

public function testOverride(): void
Expand All @@ -123,17 +125,6 @@ public function testOverrideAllowsExistingInstance(): void
self::assertSame($type, $this->registry->get('some'));
}

public function testOverrideWithAlreadyRegisteredInstance(): void
{
$newType = new TextType();

$this->registry->register('first', $newType);
$this->registry->register('second', new StringType());

$this->expectException(Exception::class);
$this->registry->override('second', $newType);
}

public function testOverrideWithUnknownType(): void
{
$this->expectException(Exception::class);
Expand Down

0 comments on commit 96c2ebf

Please sign in to comment.