decodelabs/archetype

简单的命名库加载器

v0.3.7 2024-07-31 22:00 UTC

README

PHP from Packagist Latest Version Total Downloads GitHub Workflow Status PHPStan License

PHP简单的命名库加载器

Archetype提供了一个通用的前端,用于通过可扩展的插件架构解析具有命名接口的实现类。

DecodeLabs博客上获取新闻和更新。

安装

通过Composer安装

composer require decodelabs/archetype

用法

导入

Archetype使用VeneerDecodeLabs\Archetype下提供一个统一的接口。您可以通过这个静态接口访问所有主要功能,而不会影响测试和依赖注入。

功能

当设计需要根据命名约定加载任意扩展类的插件库时,请使用Archetype。

通过将名称映射到可扩展和可定制的解析器结构中的类,Archetype允许快速、可靠地创建松散耦合的插件生态系统。

示例

// Main library
namespace My\Library
{

    use DecodeLabs\Archetype;

    interface Thing {}

    class Factory {

        public static function loadThing(string $name): Thing
        {
            // Resolve name to class for Thing interface
            $class = Archetype::resolve(Thing::class, $name);

            return new $class();
        }
    }
}


// Thing implementations
namespace My\Library\Thing
{

    use My\Library\Thing;

    class Box implements Thing {}
    class Potato implements Thing {}
    class Dog implements Thing {}
}



// Calling code
namespace My\App
{

    use My\Library\Factory;

    $box = Factory::loadthing('Box');
    $potato = Factory::loadThing('Potato');
    $dog = Factory::loadThing('Dog');
}

解析器

Archetype使用Resolvers的层次结构将名称转换为类。默认情况下,Handler将回退到Resolver\Generic实例,该实例只需在关联接口的命名空间中定位具有名称的类。

在上面的示例中,My\Library\Thing的实现可以在My\Library\Thing\*中找到。

自定义解析器

然而,Resolver\Archetype实现还会自动在同一位置查找自定义Resolver类,该位置与目标接口相同,名称为<Interface>Archetype

以下示例将替换默认功能,并导致Archetype在查找Thing实现时查找不同的位置。

namespace My\Library {

    use DecodeLabs\Archetype\Resolver;

    class ThingArchetype implements Resolver
    {

        public function getInterface(): string
        {
            return Thing::class;
        }

        public function getPriority(): int
        {
            return 10;
        }

        public function resolve(string $name): ?string
        {
            return 'Some\\Other\\Namespace\\'.$name;
        }
    }
}

多个解析器

多个Resolver实例可以针对单个接口堆叠,根据它们请求的优先级按顺序调用,第一个返回非空类名的解析器获胜。

可以通过以下方式加载替代Resolvers

use DecodeLabs\Archetype;
use My\Library\Resolver\Alternative as AlternativeResolver;

Archetype::register(new AlternativeResolver());

文件查找

Resolvers还实现了Finder接口,可以定义根据提供的名称在目标接口定义的空间内查找文件路径的方法。

当根接口定义的空间可能包含除PHP代码以外的资源时,这很有用。

具体实现将决定如何将名称映射到文件路径(没有预构建的默认Finder类)。

示例

namespace My\Library {

    use DecodeLabs\Archetype\Finder;

    class ThingArchetype implements Finder
    {

        public function getInterface(): string
        {
            return Thing::class;
        }

        public function getPriority(): int
        {
            return 10;
        }

        public function resolve(string $name): ?string
        {
            return 'Some\\Other\\Namespace\\'.$name;
        }

        public function findFile(string $name): ?string
        {
            return './some/other/namespace/'.$name.'.jpg';
        }
    }
}


namespace My\App {

    use DecodeLabs\Archetype;
    use My\Library\Thing;

    $boxImagePath = Archetype::findFile(Thing::class, 'box');
}

许可

Archetype采用MIT许可。有关完整的许可文本,请参阅LICENSE