교량 모델-디자인 모델이 전단 수요를 만족시키다

교량 설계 모델은 내가 가장 이해하기 어려운 디자인 모델 중의 하나다.🤯 주의: 본고는 대상을 대상으로 프로그래밍하는 인터페이스에 대해 기본 지식을 가지고 있다고 가정한다.
본고에서, 나는 이 모델이 무엇인지, 어떻게 사용하는지, 그리고 현재 전방 공간 (psst) 에서 사용되고 있는 예시를 설명할 것이다🚀).
우리는 몇 가지 일을 되돌아볼 것이다.
  • 뭐예요?🤔
  • 분해해 봅시다.😱
  • 그런데 왜?😐
  • 어디서 실제 응용을 찾을 수 있습니까?🚀
  • 어디서 사용할 수 있습니까?🎉
  • 이게 어떻게 된 일입니까?🤔


    브리지 모델은 조합이 계승보다 우수한 부분으로 여겨질 수 있다.그것은 본질적으로 추상과 실현 사이에 다리를 놓는 것이다.이 용어들은 약간의 혼란을 일으킬 수 있으니, 우리가 그것들을 분명히 하자.
  • 구현 - 코드 라이브러리의 모든 대상이 사용할 수 있는 특정한 행위를 설명하는 인터페이스입니다.그것은 인터페이스에 정의된 계약을 준수하는 여러 가지 구체적인 실현을 할 수 있다.
  • 추상 - 이 대상은 하나의 API를 제공할 것이고 이 API는 밑바닥으로 실현될 것이다.그것은 정상을 실현하는 층을 충당하고 필요하면 계승을 통해 더욱 세분화할 수 있다.
  • 좋아, 충격적이야.🤯 나는 읽기에 좀 보송보송하다는 것을 안다.
    UML 그림을 빨리 봅시다. (한숨은 쉬지만 도움이 됩니다.)

    그림에서 볼 수 있듯이 패턴은 두 인터페이스를 분리할 수 있으며 대상의 세부 사항을 정의할 수 있다. 이런 상황에서 대상의 형상 유형과 형상의 색깔을 정의할 수 있다.
    우리는 여러 가지 색깔이나 여러 가지 모양을 만들 수 있으며, 그 중 하나가 다른 하나에 영향을 미칠까 봐 걱정하지 않아도 된다. 따라서 코드 라이브러리의 느슨한 결합이 증가할 것이다.🔥

    분해해달래요.😱


    위의 예를 기억해라. 추상은 우리의 Shape 클래스이고, 우리의 실현은 Color 클래스이다.
    추상화는 클래스의 속성을 통해 이루어진 인용을 포함하고 (따라서 조합이 계승보다 우선하기 때문에) 우리의 예에서 Shape에는 Color 속성이 있다.색 약속을 실현하는 모든 종류는 모든 형상 속성에 사용할 수 있습니다.
    추상적인 사용자는 밑바닥의 실현을 걱정할 필요가 없고 모델 자체도 추상과 실현 간의 해이한 결합을 증가시켰다.
    만약 네가 나와 같다면, 코드를 보면 네가 생각을 정리하는 데 도움을 줄 수 있다.그럼 우리 이렇게 하자!
    이러한 예에서는 TypeScript를 사용합니다.
    // Define an interface for the Implementation
    interface Color {
        log(): string;
    }
    
    // Define an abstract class for the Abstraction
    abstract class Shape {
        color: Color;
    
        constructor(color: Color) {
            this.color = color;
        }
    
        logMe() {
            console.log(`I am a ${this.color.log()} shape.`);
        }
    }
    
    // Create a Concrete Implementation
    class Red implements Color {
        log() {
            return 'red';
        }
    }
    
    class Blue implements Color {
        log() {
            return 'blue';
        }
    }
    
    // Create a refined Abstraction that behaves slightly differently
    class Circle extends Shape {
        constructor(color: Color) {
            super(color);
        }
    
        logMe() {
            console.log(`I am a ${this.color.log()} circle.`);
        }
    }
    
    class Triangle extends Shape {
        constructor(color: Color) {
            super(color);
        }
    }
    
    // Instantiate the circle with a concrete implementation
    const circle = new Circle(new Red());
    const triangle = new Triangle(new Blue());
    
    circle.logMe();
    // Output: I am a red circle.
    
    triangle.logMe();
    // Output: I am a blue shape.
    
    경탄할 만한!우리는 그 중 하나에 영향을 주지 않고 임의의 수량Colors이나 임의의 수량Shapes을 만들 수 있습니다!🚀🚀🚀
    간단함과 분리를 유지하면 코드의 유지보수성과 테스트성을 향상시켜 더욱 좋은 코드를 만들 수 있습니다!우리는 지금도 미래에 쉽게 새로운 형상과 색깔을 확장할 수 있다!

    그런데 왜요?😐


    우리가 왜 이런 모델을 사용하는지 몇 가지 이유를 살펴보자.
  • 브리지 모델은 추상적이고 결합을 실현하기 때문에 양자가 독립적으로 다르게 허용한다.
  • 추상적이고 실현된 것을 자신의 계승 차원 구조에 보존하고 다른 계승 차원 구조에 영향을 주지 않는 상황에서 성장할 수 있도록 한다.
  • 추상은 구체적인 실현을 알 필요가 없기 때문에 실행할 때 설정하거나 교환할 수 있으며 추상을 파괴하지 않는다.
  • 너무 좋아요. 그런데 어디서 쓸 수 있을까요?🤔

    나는 어디에서 그것의 작용을 찾을 수 있습니까?🚀


    네, 다리 모양이 아주 좋아요.그것은 우리의 느슨한 결합을 증가시킬 수 있지만, 우리는 어디에서 그것을 진정으로 사용할 수 있습니까?야외에서 그것은 어디에서 사용됩니까?
    나는 그것을 사용한다!(이 점을 지적해 주셔서 감사합니다.)
    그들은 Forms API에서 그것을 사용하여 임의 NgControl 와 임의 ControlValueAccessor 사이의 차이를 메웠다.ControlValueAccessor는 방법이 있는 인터페이스로 이를 실현하는 모든 종류는 반드시 이런 방법을 실현해야 한다.Angular는 자신의ControlValueAccessor 구현된concreate 구현을 제공하지만, 개발자라면 누구나 이 인터페이스를 실현할 수 있으며, 누구NgControl 개발자라도 사용할 수 있습니다!
    다시 말하면 Angular 프레임 이외의 실현은 프레임 안의 추상에 의해 완전히 받아들여질 수 있다!🔥🔥
    마찬가지로 개발자는 자신의 NgControl를 만들 수 있고 Angular가 제공하는 어떤 구체적인 실현도 사용할 수 있습니다!💥💥
    이것은 당신이 브리지 모드의 배후의 힘을 이해하는 데 도움을 줄 수 있기를 바랍니다. 그러나 만약 당신이 여전히 자신의 용례를 필요로 한다면 계속 읽어 주십시오.

    내가 또 어디에서 쓸 수 있겠는가?🚀


    나는 전방 세계에서 완벽한 예가 데이터 접근층이라는 것을 발견했다.
    다음과 같은 기능을 사용할 수 있습니다.
  • 실체 서비스의 추상을 정의하고 이 실체 서비스는 시스템 내 실체와 관련된 논리를 처리할 것이다.
  • API 인터페이스의 구현을 정의하여 잠재적인 백엔드 시스템 또는 API와 상호 작용할 수 있습니다.
  • 이 내용을 빠르게 살펴보겠습니다.
    실현(API 인터페이스)부터 시작하겠습니다.
    export interface IApiService {
        get<T>(): T;
        getAll<T>(): T[];
        add<T>(entity: T): void;
        update<T>(entity: T): void;
        delete<T>(entity: T): void;
    }
    
    다음은 추상화(실체 서비스)를 정의합니다.
    export abstract class EntityService {
        apiService: IApiService;
    
        constructor(apiService: IApiService) {
            this.apiService = apiService;
        }
    }
    
    좋아, 우리는 이미 추상과 실현을 설정했어.녀석들을 사용하자!
    우선, 우리는 우리의 추상적인 것을 세분화하기 위해 사용자 서비스를 만들 것이다.
    export interface User {
        id: string;
        name: string;
        email: string;
    }
    
    export class UserService extends EntityService {
        activeUser: User;
    
        constructor(apiService: IApiService) {
            super(apiService);
        }
    
        addNewUser(user: User) {
            this.apiService.add(user);
        }
    
        // Here we perform some logic custom to the UserService
        // But use the underlying bridge between the concrete
        // implementation and the abstraction to update the
        // active user after some custom logic
        setActiveUserEmail(email: string) {
            this.activeUser.email = email;
            this.apiService.update(this.activeUser);
        }
    }
    
    현재 우리는 이미 완벽한 추상이 하나 있으니, 우리는 계속해서 구체적인 실현을 창조할 것이다
    export class CustomApiService implements IApiService {
        get<T>(): T {
            // fetch the user from the api
        }
    
        getAll<T>(): T[] {
            // etc
        }
    
        add<T>(entity: T): void {
            // etc
        }
    
        update<T>(entity: T): void {
            // etc
        }
    
        delete<T>(entity: T): void {
            // etc
        }
    }
    
    좋습니다. 이제 구체적인 실현과 추상적인 세분화를 사용하겠습니다.
    const apiService = new CustomApiService();
    const userService = new UserService(apiService);
    
    userService.addNewUser({...} as User);
    
    경탄할 만한!우리UserService는 실현된 본질을 알 필요가 없고, 여전히 예상대로 운행할 수 있다.
    만약 다음 수요에 변화가 생기면 갑자기 우리가 더 이상 사용할 수 없게 된다IApiService면 무슨 일이 일어날까!😱
    겁먹지 마, 다리 모양이 여기 있어!😍
    새로운 구체적인 실현을 만들어서 CustomApiService에 제공하기만 하면 된다.
    // Create new implementation
    export class MongoDBService implements IApiService {
       // etc
    }
    
    // Swap out the api service
    const apiService = new MongoDbService();
    
    // No need to change the rest!
    const userService = new UserService(apiService);
    
    userService.addNewUser({...} as User);
    
    너무 좋아요!🚀🚀🚀
    조금 더 배웠으면 좋겠어(더?)본문의 브리지 모드에 대한 잠재적인 용례, 그리고 Angular에서 어떻게 사용하는지.
    질문이 있으시면 언제든지 아래 질문이나 트위터에 연락 주세요.

    좋은 웹페이지 즐겨찾기