자바 빌더 모드

1. 소개

소프트웨어 개발 과정에서 때때로 특정 단계에서 결합 된 여러 하위 구성 요소로 구성된 복잡한 개체를 만들어야하는 경우가 있습니다. 예를 들어, 컴퓨터는 CPU, 마더 보드, 메모리, 하드 디스크, 그래픽 카드, 섀시, 모니터, 키보드, 마우스 및 기타 구성 요소로 조립됩니다. 구매자는 컴퓨터를 스스로 조립할 수 없지만 컴퓨터 판매 회사에 구성 요구 사항을 알려줍니다. 컴퓨터 판매 회사는 기술자를 배치하여 컴퓨터를 조립 한 다음 컴퓨터를 구입하려는 구매자에게 건네줍니다.

게임 속 캐릭터, 성별, 성격, 능력, 얼굴 형, 체형, 의복, 헤어 스타일 및 기타 특성이 다른 것과 같은 삶의 예가 많이 있습니다. 또한 스티어링 휠, 엔진, 프레임, 타이어 및 기타 차량 구성 요소 또한 다양하며 각 이메일의 발신자, 수신자, 제목, 내용, 첨부 파일 등도 다릅니다.

위의 모든 제품은 여러 부품으로 구성되어 있으며 각 부품을 유연하게 선택할 수 있지만 생성 단계는 비슷합니다. 이러한 유형의 제품 생성은 앞서 소개 한 팩토리 모델로 설명 할 수 없으며 빌더 모델 만 이러한 유형의 제품 생성을 잘 설명 할 수 있습니다.

2. 빌더 모드의 특징

빌더 (Builder) 패턴의 정의 : 동일한 구성 프로세스가 다른 표현을 생성 할 수 있도록 복잡한 객체의 구성을 표현에서 분리하는 것을 말합니다.이 디자인 패턴을 빌더 패턴이라고합니다. 복잡한 개체를 여러 개의 간단한 개체로 분해 한 다음 단계별로 빌드합니다. 변하지 않는 것과 변하지 않는 것, 즉 제품의 구성 요소는 변하지 않지만 각 부분을 유연하게 선택할 수 있습니다.

이 모드의 주요 장점은 다음과 같습니다.

  1. 우수한 캡슐화, 구성 및 프리젠 테이션 분리.
  2. 우수한 확장 성, 각 특정 빌더는 서로 독립적이므로 시스템 분리에 도움이됩니다.
  3. 클라이언트는 제품의 내부 구성에 대한 세부 사항을 알 필요가 없으며 빌더는 다른 모듈에 영향을주지 않고 생성 프로세스를 점진적으로 개선 할 수있어 세부적인 위험을 제어하는 ​​데 편리합니다.

** 단점은 다음과 같습니다. **

  1. 제품의 구성 요소는 동일해야하므로 사용 범위가 제한됩니다.
  2. 제품의 내부 변경이 복잡하고 제품의 내부 변경이 발생하면 빌더도 동시에 수정해야하므로 유지 보수 비용이 높아집니다.

빌더 (Builder) 모드와 팩토리 모드의 초점은 다릅니다. 빌더 모드는 부품의 조립 프로세스에 초점을 맞추고, 팩토리 방법 모드는 부품의 생성 프로세스에 더 초점을 맞추지 만 둘은 다음에서 사용할 수 있습니다. 콤비네이션.

3. 패턴의 구조와 실현

빌더 모델은 제품, 추상 빌더, 콘크리트 빌더, 커맨더의 네 가지 요소로 구성되며 이제 기본 구조와 구현 방법을 분석해 보겠습니다.

  • 패턴의 구조

Builder 모드의 주요 역할은 다음과 같습니다.

  1. 제품 역할 (제품) : 여러 구성 요소를 포함하는 복잡한 개체이며 각 구성 요소는 특정 빌더에 의해 생성됩니다.
  2. 추상 빌더 (Builder) : 제품의 다양한 하위 구성 요소를 생성하기위한 추상 메서드를 포함하는 인터페이스이며 일반적으로 복잡한 제품을 반환하는 getResult () 메서드도 포함합니다.
  3. Concrete Builder : Builder 인터페이스를 구현하고 복잡한 제품의 각 구성 요소에 대한 구체적인 생성 방법을 완성합니다.
  4. Director : 복잡한 객체 생성을 완료하기 위해 Builder 객체에서 구성 요소 구성 및 조립 방법을 호출합니다. Director는 특정 제품 정보를 포함하지 않습니다.

여기에 사진 설명 삽입

  • 패턴의 실현 :

제품 역할 : 여러 구성 요소를 포함하는 복잡한 개체

class Product {
    
    
    private String partA;
    private String partB;
    private String partC;

    public void setPartA(String partA) {
    
    
        this.partA = partA;
    }

    public void setPartB(String partB) {
    
    
        this.partB = partB;
    }

    public void setPartC(String partC) {
    
    
        this.partC = partC;
    }

    public void show() {
    
    
        //显示产品的特性
    }
}

추상 빌더 : 제품의 다양한 하위 구성 요소를 작성하기위한 추상 메소드를 포함합니다.

abstract class Builder {
    
    
    //创建产品对象
    protected Product product = new Product();

    public abstract void buildPartA();

    public abstract void buildPartB();

    public abstract void buildPartC();

    //返回产品对象
    public Product getResult() {
    
    
        return product;
    }
}

콘크리트 빌더 : 추상 빌더 인터페이스 구현

public class ConcreteBuilder extends Builder {
    
    
    public void buildPartA() {
    
    
        product.setPartA("建造 PartA");
    }

    public void buildPartB() {
    
    
        product.setPartB("建造 PartB");
    }

    public void buildPartC() {
    
    
        product.setPartC("建造 PartC");
    }
}

Commander : 빌더에서 메소드를 호출하여 복잡한 개체 생성 완료

class Director {
    
    
    private Builder builder;

    public Director(Builder builder) {
    
    
        this.builder = builder;
    }

    //产品构建与组装方法
    public Product construct() {
    
    
        builder.buildPartA();
        builder.buildPartB();
        builder.buildPartC();
        return builder.getResult();
    }
}

고객 등급

public class Client {
    
    
    public static void main(String[] args) {
    
    
        Builder builder = new ConcreteBuilder();
        Director director = new Director(builder);
        Product product = director.construct();
        product.show();
    }
}

4. 패턴 적용

Builder 모델을 사용하여 거실 장식을 설명합니다.

분석 : 거실 장식은 벽 장식, TV 선택, 소파 구매 및 레이아웃 등을 포함하는 복잡한 프로세스입니다. 고객은 프로젝트 관리자에게 장식 요구 사항을 알리고 프로젝트 관리자는 장식 작업자에게 단계별로 지시하고 마지막으로 전체 거실의 장식 및 레이아웃을 완료하므로이 예제는 빌더 모드에서 구현하는 데 더 적합합니다.

여기 거실은 벽, TV, 소파 및 기타 구성 요소를 포함한 제품입니다. 콘크리트 장식 작업자는 벽, TV 및 소파의 장식과 레이아웃을 담당하는 콘크리트 건축업자입니다. 프로젝트 관리자는 지휘자이며 장식 작업자가 장식을 수행하도록 지시하는 책임이 있습니다.

여기에 사진 설명 삽입

public class ParlourDecorator {
    
    
    public static void main(String[] args) {
    
    
        try {
    
    
            Decorator d;
            d = new ConcreteDecorator1();
            //d = new ConcreteDecorator2();
            ProjectManager m = new ProjectManager(d);
            Parlour p = m.decorate();
            p.show();
        } catch (Exception e) {
    
    
            System.out.println(e.getMessage());
        }
    }
}

//产品:客厅
class Parlour {
    
    
    private String wall;    //墙
    private String TV;    //电视
    private String sofa;    //沙发 

    public void setWall(String wall) {
    
    
        this.wall = wall;
    }

    public void setTV(String TV) {
    
    
        this.TV = TV;
    }

    public void setSofa(String sofa) {
    
    
        this.sofa = sofa;
    }

    public void show() {
    
    
        //...
    }
}

//抽象建造者:装修工人
abstract class Decorator {
    
    
    //创建产品对象
    protected Parlour product = new Parlour();

    public abstract void buildWall();

    public abstract void buildTV();

    public abstract void buildSofa();

    //返回产品对象
    public Parlour getResult() {
    
    
        return product;
    }
}

//具体建造者:具体装修工人1
class ConcreteDecorator1 extends Decorator {
    
    
    public void buildWall() {
    
    
        product.setWall("w1");
    }

    public void buildTV() {
    
    
        product.setTV("TV1");
    }

    public void buildSofa() {
    
    
        product.setSofa("sf1");
    }
}

//具体建造者:具体装修工人2
class ConcreteDecorator2 extends Decorator {
    
    
    public void buildWall() {
    
    
        product.setWall("w2");
    }

    public void buildTV() {
    
    
        product.setTV("TV2");
    }

    public void buildSofa() {
    
    
        product.setSofa("sf2");
    }
}

//指挥者:项目经理
class ProjectManager {
    
    
    private Decorator builder;

    public ProjectManager(Decorator builder) {
    
    
        this.builder = builder;
    }

    //产品构建与组装方法
    public Parlour decorate() {
    
    
        builder.buildWall();
        builder.buildTV();
        builder.buildSofa();
        return builder.getResult();
    }
}

5. 대체 크리에이터 모드

클래스의 생성자 매개 변수 수가 4 개를 초과하고 이러한 매개 변수 중 일부가 선택 사항 인 경우 생성자 모드 사용을 고려하십시오.

클래스에 4 개 이상의 생성자 매개 변수가 있고 이러한 매개 변수 중 일부가 선택 사항 인 경우 일반적으로 객체를 생성하는 두 가지 방법이 있습니다. 예를 들어, 이제 다음과 같은 컴퓨터 클래스 Computer가 있습니다. 여기에서 cpu와 ram은 필수 매개 변수이고 나머지 세 개는 선택적 매개 변수입니다.이 클래스의 인스턴스를 구성하는 방법 일반적으로 두 가지 일반적인 방법이 있습니다.

public class Computer {
    
    
    private String cpu;//必须
    private String ram;//必须
    private int usbCount;//可选
    private String keyboard;//可选
    private String display;//可选
}

첫 번째 : 다음 코드와 같이 우리가 자주 사용하는 생성자 패턴 (텔레 스코핑 생성자 패턴) 접기

public class Computer {
    
    
     ...
    public Computer(String cpu, String ram) {
    
    
        this(cpu, ram, 0);
    }
    public Computer(String cpu, String ram, int usbCount) {
    
    
        this(cpu, ram, usbCount, "罗技键盘");
    }
    public Computer(String cpu, String ram, int usbCount, String keyboard) {
    
    
        this(cpu, ram, usbCount, keyboard, "三星显示器");
    }
    public Computer(String cpu, String ram, int usbCount, String keyboard, String display) {
    
    
        this.cpu = cpu;
        this.ram = ram;
        this.usbCount = usbCount;
        this.keyboard = keyboard;
        this.display = display;
    }
}

두 번째 : Javabean 모드, 아래와 같이

public class Computer {
    
    
        ...

    public String getCpu() {
    
    
        return cpu;
    }
    public void setCpu(String cpu) {
    
    
        this.cpu = cpu;
    }
    public String getRam() {
    
    
        return ram;
    }
    public void setRam(String ram) {
    
    
        this.ram = ram;
    }
    public int getUsbCount() {
    
    
        return usbCount;
    }
...
}

그렇다면이 두 가지 방법의 단점은 무엇입니까?

첫 번째는 주로 사용하고 읽는 것이 불편합니다. 클래스의 생성자를 호출하려면 먼저 어떤 것을 사용할 것인지 결정해야하고 그 다음에는 많은 매개 변수가 있다고 상상할 수 있습니다. 이러한 매개 변수의 유형이 많고 동일한 경우에는 알아 내야합니다. 이 매개 변수의 매개 변수입니다. 의미는 쉽게 전달됩니다.

두 번째 방법으로 개체의 상태가 구성 과정에서 변경되기 쉬워서 오류가 발생합니다. 해당 클래스의 속성은 단계적으로 설정되기 때문에 오류가 발생하기 쉽습니다.

빌더 모드 구현

  1. Computer에 정적 내부 클래스 Builder를 만든 다음 Computer의 매개 변수를 Builder 클래스에 복사합니다.
  2. Computer에서 개인 생성자를 만듭니다. 매개 변수는 Builder 유형입니다.
  3. Builder에서 공용 생성자를 만듭니다. 매개 변수는 Computer, cpu 및 ram에 필요한 매개 변수입니다.
  4. Builder에서 설정 기능을 만들고 컴퓨터의 이러한 선택적 매개 변수에 값을 할당하면 반환 값이 Builder 유형의 인스턴스입니다.
  5. Builder에서 build () 메서드를 만들고 그 안에 Computer 인스턴스를 빌드하고 반환합니다.

암호

public class Computer {
    
    
    private final String cpu;//必须
    private final String ram;//必须
    private final int usbCount;//可选
    private final String keyboard;//可选
    private final String display;//可选

    private Computer(Builder builder){
    
    
        this.cpu=builder.cpu;
        this.ram=builder.ram;
        this.usbCount=builder.usbCount;
        this.keyboard=builder.keyboard;
        this.display=builder.display;
    }
    public static class Builder{
    
    
        private String cpu;//必须
        private String ram;//必须
        private int usbCount;//可选
        private String keyboard;//可选
        private String display;//可选

        public Builder(String cup,String ram){
    
    
            this.cpu=cup;
            this.ram=ram;
        }

        public Builder setUsbCount(int usbCount) {
    
    
            this.usbCount = usbCount;
            return this;
        }
        public Builder setKeyboard(String keyboard) {
    
    
            this.keyboard = keyboard;
            return this;
        }
        public Builder setDisplay(String display) {
    
    
            this.display = display;
            return this;
        }        
        public Computer build(){
    
    
            return new Computer(this);
        }
    }
  //省略getter方法
}s

사용하다

클라이언트에서 체인 호출을 사용하여 단계별로 개체를 빌드합니다.

Computer computer=new Computer.Builder("因特尔","三星")
                .setDisplay("三星24寸")
                .setKeyboard("罗技")
                .setUsbCount(2)
                .build();

위의 내용은 Java에서 Builder를 사용하는 단순화 된 방법으로 위에서 소개 한 기존의 Builder 모드와 다소 다릅니다. 디렉터의 역할을 생략하고 구성 알고리즘을 고객에게 건네주고 두 번째로 빌드 할 제품 클래스에 빌더를 작성하고 마지막으로 연결 호출을 사용합니다.

추천

출처blog.csdn.net/saienenen/article/details/111668146