응용 디자인 모델:DI 환경에서의 생성기와 공장 모델
RouteBuilder
이 있었어요.(동시에
ViewBuider
으로 명칭 변경) Sulu은 말 그대로Builder pattern, Sulu에서 다른 경로 만들기
신청빌더 모드 제외
Factory pattern도 사용했다.
나에게 있어서 이러한 모델을 배우는 데 가장 어려운 부분은 의미가 있을 때 아이디어를 얻는 것이다.그래서 난
디자인 모델에 대한 나의 사용을 보고하고 다른 사람들에게 그것을 어떻게 응용할 것인가에 대한 생각을 주기를 바란다.
이것은 건축가와 공장 모델을 포함하는 잠재적인 시리즈의 첫 번째 논문이다.
추상 모형의 결점
우리가 왜 이런 모델을 선택했는지 더 잘 이해하기 위해서, 나는 우리가 존재하는 불협화음을 설명하려고 한다
예전에 처리해야 할용례는 우리가 당시에
Route
이라고 불렀던 것을 만드는 것이다.View
) 저희 것입니다.Single Page Application . 이
Route
에는URL 자체도 React 구성 요소에 대한 참조입니다.
URL이 활성 상태입니다.시스템에서 루트를 인용해야 하기 때문에, 루트에 이름 파라미터를 추가했습니다.
이것들은 노선의 관건적인 부분이며, 항상 제시해야 하기 때문에, 우리는 그것들을 넣기로 결정했다
Route
류.우리는 모든 노선에 단독 React 구성 요소를 실시하고 싶지 않기 때문에그것들은 노선상의 옵션을 사용하여 설정할 수 있다.
(new Route('sulu_tag.datagrid', '/tags', 'sulu_admin.datagrid'))
->addOption('title', 'sulu_tag.tags')
->addOption('resourceKey', 'tags')
->addOption('adapters', ['table'])
->addOption('addRoute', 'sulu_tag.add_form.detail')
->addOption('editRoute', 'sulu_tag.edit_form.detail');
위의 예에서는 이러한 Route
의 PHP 정의를 보여 줍니다.sulu_tag.datagrid
은 노선의 명칭, /tags
브라우저 주소 표시줄에 표시할 경로입니다. sulu_admin.datagrid
은 참조입니다.반응 전단의 부품.이 구성 요소는 고도로 설정할 수 있는 방식으로 이루어졌기 때문에 우리는
이전 예의 탭에만 사용하고, 우리 시스템의 모든 다른 종류의 실체에도 사용합니다.이것은
resourceKey
옵션에 설명된 내용입니다.내가 말하고 싶은 것은, 만약 네가 우리의 영역에 대해 조금이라도 알고 있다면, 그 중 대부분이 무엇인지 알아맞힐 수 있다는 것이다
옵션이 작동하고 있습니다.그러나 다음 코드를 작성하는 개발자에게는 여전히 번거롭다.
title
, resourceKey
등)IDE가 auto를 통해 지원되지 않음완성
Route
은 여러 가지 유형의 옵션에 대한 추상적인 것이기 때문입니다.노선
Route
의 실례는 하드 인코딩으로 바꿀 수 없습니다.이것은 중국에서 불필요한 것이다우리의 경우, 그러나 다른 상황에서는 필요할 수도 있다.
Route
가지의 생각을 가지고 있는 것을 좋아한다.이것은 우리가 전방 코드에서 반드시 처리해야 할 유일한 사례이기 때문이다.그렇지 않으면 우리는 어쩔 수 없이 한 문제를 처리할 것이다
FormRoute
, DatagridRoute
등은 우리의 전단 코드에서 보기에 좋지 않다.다행히도, Builder 모드는 정의가 좋은 인터페이스를 도입하여 만들 수 있습니다
이 노선들은 동시에
Route
등급을 유지한다.생성기 모드를 사용하여 실례화된 대상
빌더 모드는 OOP 환경에서 처리된다는 것을 의미하는 창조적 모드입니다.
실례화 대상.이것은
Builder
클래스를 만들어서 이를 실현한다. 이 클래스는 부분적으로 클래스를 구축할 수 있는 인터페이스를 가지고 있다반대, 반대하다그래서 구축할 때 반드시 많은 다른 것을 알아야 하는 대상이 있어도 당신은
정보 및
대상 실례.
Builder
의 실현을 살펴보겠습니다. RouteBuilder
이 적용되었습니다.위
Builder
과정의 모델:<?php
namespace Sulu\Bundle\AdminBundle\Admin\Routing;
class DatagridRouteBuilder
implements DatagridRouteBuilderInterface
{
private $route;
public function __construct(string $name, string $path)
{
$this->route = new Route(
$name,
$path,
'sulu_admin.datagrid'
);
}
public function setResourceKey(
string $resourceKey
): DatagridRouteBuilderInterface
{
$this->route->setOption('resourceKey', $resourceKey);
return $this;
}
public function setTitle(
string $title
): DatagridRouteBuilderInterface
{
$this->route->setOption('title', $title);
return $this;
}
// Omitted some of the methods for brevity
public function getRoute(): Route
{
if (!$this->route->getOption('resourceKey')) {
throw new \DomainException(
'A route for a datagrid view needs a '
. '"resourceKey" option. You have likely '
. 'forgotten to call the "setResourceKey" '
. 'method.'
);
}
// Omitted more checks for brevity
return clone $this->route;
}
}
따라서 위의 Route
의 모든 단점과 달리 Route
의 실례화는이런 것들로 대체되다.
(new DatagridRouteBuilder('sulu_tag.datagrid', '/tags'))
->setResourceKey('tags')
->setTitle('sulu_tag.tags')
->addDatagridAdapters(['table'])
->setAddRoute('sulu_tag.add_form.detail')
->setEditRoute('sulu_tag.edit_form.detail')
->getRoute();
따라서 Route
이 출시됨에 따라 다음과 같은 몇 가지 문제를 해결했습니다.DatagridRouteBuilder
옵션에서 Route
으로 돌아가기 전에 해당 옵션을 확인할 수 있습니다.getRoute
을 도입함으로써 실례화 과정을 바꿀 수 있다.DatagridRouteBuilderInterface
을 제외하고 DatagridBuilder
을 출시했습니다.매우 비슷하고 이런 문제들도 해결했다.가장 좋은 것은 이 두 건설자의
FormRouteBuilder
방법이다여전히
getRoute
대상을 되돌려줍니다. 따라서 우리는 사용할 수 있는 모든 경로를 쉽게 교체하고 그것을 어떻게 처리하는지 알 수 있습니다.상기 예시에서
Route
류는 즉시 실례화되었고, 기타 Route
방법은 호출되었다Builder
방법으로 정확한 값을 분배한다.좋습니다. 창설을 미룰 수도 있습니다.대상의 Getter 방법으로 구조 함수를 정의할 수 있습니다.
대상은 처음부터 효과적이며, 동시에 이러한 대상을 만드는 것은 사용자에게 편안하다
개발상.
또 다른 장점은
setOption
대상도 매개 변수로 참여자에게 전달할 수 있다는 것이다객체 작성 프로세스응용 프로그램에서
Builder
에 추가할 설정이 있다고 가정하십시오노선이 경우 함수에서 이 섹션을 수행할 수 있습니다.
<?php
function enhanceDatagridRoute(DatagridRouteBuilder $builder) {
$builder->addDatagridAdapters(['table']);
}
술루에서 우리는 similar approach을 사용했다Builder
of Doctrine은 몇 번.<?php
function enhance(
QueryBuilder $queryBuilder,
UserInterface $user = null,
string $entityClass,
string $entityAlias
) {
$queryBuilder->leftJoin(
AccessControl::class,
'accessControl',
'WITH',
'accessControl.entityClass = :entityClass '
. 'AND accessControl.entityId = ' . $entityAlias . '.id'
);
$queryBuilder->setParameter('entityClass', $entityClass);
}
이 Sulu 코드 라이브러리의 간략한 예는 액세스 제어 테이블에 연결되며우리가 제기한 모든 문제.이런 방식은
Datagrid
모델을 사용하여 실현된 것이다.비슷한 일을 하다plain DQL
처음부터 조회를 더욱 조심스럽게 구축해야 하기 때문에 매우 번거로울 수 있다
그리고 좋은 개발자 체험은 아니에요.그래서 저는 거의 항상 DQL 대신
QueryBuilder
을 사용합니다.건설업자로 하여금 공장 모델에 따라 케이블을 다시 설치하게 하다
Builder
이 출시되었으며 교체는 다음과 같습니다.QueryBuilder
이 장점이다.그러나 사실상 이것은 여전히 불가능하다. 왜냐하면 유일한 차이점은다른 종류의 실례화는 이미 하드코딩을 통과했다.
DatagridRouteBuilderInterface
에는 별도의 인스턴스가 필요합니다.현재 구축 과정에 대한 상태가 포함되어 있기 때문에 생성 중인 모든 대상에 대해이것은 우리가 쉽게 할 수 없다는 것을 의미한다
하나의 서비스가 항상 하나의 실례로 간주되기 때문에, 예를 들어 Symfony의 의존 주입을 사용하여 주입합니다.
반대로 또 다른 창조 모델인 공장 모델을 사용할 수 있다.
공장은 구축기 모드와 다르지만 대상의 창설도 봉인했다.
그러나 이는 우리가 Builder와 Factory 모드를 결합하는 것을 막아서는 안 된다.아주 중요한 차이점
이러한 패턴 사이에서
Builder
은 새로운대상이기 때문에 어떤 상태도 유지할 필요가 없다.이것은 우리가 이런 종류의 구축을 피할 수 있다는 것을 의미한다
우리의 코드에 직접 (의존항이 상하문에 주입되는 것은 나쁜 방법), 그리고 주입할 수 있다
DatagridRouteBuilder
. 이는 전달된 매개 변수를 바꾸기만 하면 Factory
을 쉽게 바꿀 수 있다는 것을 의미한다이
Factory
의 클래스를 사용하는 구조 함수까지.아래의 코드 단편은 이런 공장의 외관을 보여 준다예를 들면 다음과 같습니다.
<?php
namespace Sulu\Bundle\AdminBundle\Admin\Routing;
class RouteBuilderFactory implements RouteBuilderFactoryInterface
{
public function createDatagridRouteBuilder(
string $name,
string $path
): DatagridRouteBuilderInterface
{
return new DatagridRouteBuilder($name, $path);
}
public function createFormRouteBuilder(
string $name,
string $path
): FormRouteBuilderInterface
{
return new FormRouteBuilder($name, $path);
}
}
이렇게 하면 위 Factory
의 생성이 변경됩니다.$this->routeBuilderFactory
->createDatagridRouteBuilder('sulu_tag.datagrid', '/tags')
->setResourceKey('tags')
->setTitle('sulu_tag.tags')
->addDatagridAdapters(['table'])
->setAddRoute('sulu_tag.add_form.detail')
->setEditRoute('sulu_tag.edit_form.detail')
->getRoute();
Factory
구성원 변수는 의존항 주입을 통해 값을 부여하여 코드의 일부가 될 수 있다중복 테스트 가능.임무 완수!
결론
DatagridRoute
과 routeBuilderFactory
모드를 응용함으로써 우리는 우리의 코드를 더욱 깨끗하고 테스트할 수 있으며 자기 기록할 수 있게 한다.그것Factory
과 Builder
이 모델이기 때문에 다른 개발자들이 모두 아는 언어도 도입했다이것은 모두가 다 알고 있는 것이다.이 해결 방안은 당신의 영역을 진정으로 의미 있는 방식으로 모델링할 수 있도록 허용합니다. 왜냐하면 당신은
모든 정보를 사용할 수 있을 때까지 객체 작성을 지연합니다.그래서 구조기는 한 가지를 쓸 수 있어요.
객체 상태가 유효한지 확인합니다.
일반적으로 여러 단계를 통해 대상을 만들고 싶을 때
Builder
모드가 좋습니다.하지만 난네가 복잡한 대상 구조기를 가지고 있을 때, 그것도 매우 좋다. 왜냐하면 그것은 일곱 번째 구조기가 무엇인지 추측하는 문제를 해결했기 때문이다
호출 코드에
Factory
이 표시됩니다.따라서 PHP 버전을 지원하지 않는 경우 해당 버전을 대체할 수도 있습니다.named parameters 지원.
Reference
이 문제에 관하여(응용 디자인 모델:DI 환경에서의 생성기와 공장 모델), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/danrot90/applying-design-patterns-the-builder-and-factory-pattern-in-a-di-context-kb텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)