빌더 모드 (8)

무슨 일이 있어도 희망을 가져라

이전 장에서 프로토타입 모드(7개)에 대해 간략하게 소개했으므로 아직 읽지 않은 경우 이전 장을 시청하세요.

1. 빌더 모드

루키 튜토리얼의 빌더 패턴 소개를 참조하세요: https://www.runoob.com/design-pattern/builder-pattern.html

빌더 패턴(Builder Pattern)은 여러 개의 간단한 객체를 사용하여 복잡한 객체를 단계별로 빌드합니다.

이러한 유형의 디자인 패턴은 객체를 생성하는 최적의 방법을 제공하는 생성 패턴입니다.

Builder 클래스는 최종 개체를 단계별로 구성합니다. Builder 클래스는 다른 개체와 독립적입니다.

1.1 소개

의도 : 동일한 구성 프로세스가 다른 표현을 만들 수 있도록 복잡한 구성을 해당 표현에서 분리합니다.

주요 솔루션 : 소프트웨어 시스템에서 때때로 특정 알고리즘을 가진 각 부분의 하위 개체로 구성된 "복합 개체"의 생성에 직면합니다. 요구 사항의 변경으로 인해 이 복잡한 개체의 각 부분은 종종 직면하게 됩니다. 급격하게 변화하고 있지만 이들을 결합하는 알고리즘은 상대적으로 안정적입니다.

사용 시기 : 일부 기본 구성 요소는 변경되지 않지만 조합이 자주 변경되는 경우.

수정 방법 : 변경과 불변을 분리합니다.

키 코드 : 빌더: 인스턴스 생성 및 제공, 디렉터: 빌드된 인스턴스의 종속성을 관리합니다.

적용 예 :

1. KFC에 가면 햄버거, 콜라, 감자튀김, 닭날개튀김 등은 꾸준하지만 이들의 조합은 끊임없이 바뀌어 이른바 '정식'이 된다.

2. JAVA의 StringBuilder.

장점 : 1. 빌더가 독립적이고 확장이 용이합니다. 2. 디테일한 리스크 관리가 용이합니다.

단점 : 1. 제품에 공통점이 있어야 하며 범위가 제한적입니다. 2. 내부 변경이 복잡하면 시공 클래스가 많을 것입니다.

사용 시나리오 : 1. 생성할 개체의 내부 구조가 복잡합니다. 2. 생성해야 하는 객체의 내부 속성은 서로 의존적입니다.

참고 : 공장 모드와 다른 점은 빌더 모드가 부품 조립 순서에 더 주의를 기울인다는 것입니다.

구성 역할 특정한 관계 효과
제품 콘크리트 제작자가 구성할 복합 객체 콘크리트 제작자가 구성할 복합 객체
콘크리트 빌더 SimpleHouseBuilder, HightHouseBuilder 개별 부품 생산 빌더 인터페이스를 구현하는 클래스 및 특정 빌더는 빌더 인터페이스에서 정의한 메소드를 구현합니다.
추상 빌더(Bulider) 주택 건설업자 구성 단계 정의 Product 개체의 각 구성 요소를 만들기 위한 여러 메서드를 정의하는 것 외에도 Product 개체를 반환하는 메서드를 정의해야 합니다.
감독 하우스디렉터 단계에 따라 부품을 조립하고 제품으로 돌아가십시오. 단계에 따라 부품을 조립하고 제품으로 돌아가십시오.

이미지-20230614110041817

2. 시행

집을 짓는 작업을 정의하는 것과 같은

2. 빌더 모드를 사용하지 않는 사람

2.1.1 추상 클래스의 정의

추상 클래스를 정의합니다.

public abstract class AbstractHouse {
    
    
    protected abstract void buildBasic();
    protected abstract void buildWalls();
    protected abstract void buildRoofed();

    public void build () {
    
    
        buildBasic();
        buildWalls();
        buildRoofed();
    }
}

2.1.2 서브클래스 구현

@Slf4j
public class SimpleHouse extends AbstractHouse{
    
    
    @Override
    protected void buildBasic() {
    
    
        log.info("简单楼打地基");
    }

    @Override
    protected void buildWalls() {
    
    
        log.info("简单楼砌墙壁");
    }

    @Override
    protected void buildRoofed() {
    
    
        log.info("简单楼地板");
    }
}
@Slf4j
public class HightHouse extends AbstractHouse{
    
    

    @Override
    protected void buildBasic() {
    
    
        log.info("高楼打地基");
    }

    @Override
    protected void buildWalls() {
    
    
        log.info("高楼砌墙壁");
    }

    @Override
    protected void buildRoofed() {
    
    
        log.info("高楼地板");
    }
}

2.1.3 시험방법

 @Test
    public void oneTest() {
    
    
        AbstractHouse simpleHouse = new SimpleHouse();
        simpleHouse.build();

        AbstractHouse hightHouse  = new HightHouse();
        hightHouse.build();
    }

이미지-20230614111038377

이 방법은 디자인 원칙에 맞지 않습니다.

2. 투 빌더 모드

2.2.1 제품의 정의

@Data
public class House {
    
    
    private String basic;
    private String wall;
    private String roofed;
}

2.2.2 추상 빌더 빌더

일반적으로 build() 메서드는 하나만 필요합니다.

public abstract class HouseBuilder {
    
    

    protected House house = new House();

    protected abstract void buildBasic();
    protected abstract void buildWalls();
    protected abstract void buildRoofed();

    public House build() {
    
    
        buildBasic();
        buildWalls();
        buildRoofed();
        return house;
    }
    /**
     一个其他的类型操作,类似于不同的套餐
     */
    public House noRoofBuild () {
    
    
        buildBasic();
        buildWalls();
        return house;
    }
}

2. 2. 3 특정 생산자 ConcreteBuilder

public class SimpleHouseBuilder extends HouseBuilder{
    
    

    @Override
    protected void buildBasic() {
    
    
        house.setBasic("地基10");
    }

    @Override
    protected void buildWalls() {
    
    
        house.setWall("砌墙2");
    }

    @Override
    protected void buildRoofed() {
    
    
        house.setRoofed("地板2");
    }
}
public class HightHouseBuilder extends HouseBuilder{
    
    

    @Override
    protected void buildBasic() {
    
    
        house.setBasic("地基100");
    }

    @Override
    protected void buildWalls() {
    
    
        house.setWall("砌墙20");
    }

    @Override
    protected void buildRoofed() {
    
    
        house.setRoofed("地板20");
    }
}

2.2.4 사령관 감독

public class HouseDirector {
    
    
    HouseBuilder houseBuilder = null;

    public HouseDirector (HouseBuilder houseBuilder) {
    
    
        this.houseBuilder = houseBuilder;
    }

    public void setHouseBuilder(HouseBuilder houseBuilder) {
    
    
        this.houseBuilder = houseBuilder;
    }

    public House build () {
    
    
        return this.houseBuilder.build();
    }

    public House noRoofBuild () {
    
    
        return this.houseBuilder.noRoofBuild();
    }
}

2.2.5 테스트 사용

    @Test
    public void twoTest() {
    
    
        HouseDirector houseDirector = new HouseDirector(new HightHouseBuilder());
        House house = houseDirector.build();
        log.info(">>> 打印高信息: {}", house);

        houseDirector.setHouseBuilder(new SimpleHouseBuilder());

        House noRoofHouse = houseDirector.noRoofBuild();
        log.info(">>> 打印低信息: {}", noRoofHouse);
        
        House house2 = houseDirector.build();
        log.info(">>> 打印低信息: {}", house2);
    }

이미지-20230614111702033

3. 공통 엔티티 클래스의 빌더

예를 들어 Student 클래스를 정의합니다.

@Builder 주석에 유의하십시오.

@Data
@Builder
public class Student {
    
    
    private Integer id;
    private String name;
    private String sex;
}

우리가 사용할 때 이렇게 사용하면 빌더입니다

@Test
    public void threeTest() {
    
    
        Student student = Student.builder().id(1).name("张三").sex("男").build();
        log.info("学生信息: {}", student);
    }

이미지-20230614111857514

소스 코드는 다음과 같이 동적으로 컴파일됩니다.

public class Student {
    
    
    private Integer id;
    private String name;
    private String sex;

    Student(Integer id, String name, String sex) {
    
    
        this.id = id;
        this.name = name;
        this.sex = sex;
    }

    public static Student.StudentBuilder builder() {
    
    
        return new Student.StudentBuilder();
    }

    public static class StudentBuilder {
    
    
        private Integer id;
        private String name;
        private String sex;

        StudentBuilder() {
    
    
        }

        public Student.StudentBuilder id(Integer id) {
    
    
            this.id = id;
            return this;
        }

        public Student.StudentBuilder name(String name) {
    
    
            this.name = name;
            return this;
        }

        public Student.StudentBuilder sex(String sex) {
    
    
            this.sex = sex;
            return this;
        }

        public Student build() {
    
    
            return new Student(this.id, this.name, this.sex);
        }

        public String toString() {
    
    
            return "Student.StudentBuilder(id=" + this.id + ", name=" + this.name + ", sex=" + this.sex + ")";
        }
    }
}

이 장의 코드는 github에 있습니다.


https://github.com/yuejianli/DesignPattern/tree/develop/Builder


시청해주셔서 감사합니다. 마음에 드셨다면 팔로우 해주세요. 다시한번 감사드립니다!!!

추천

출처blog.csdn.net/yjltx1234csdn/article/details/131204337