이 글에서는 주로 Builder의 사용법을 소개합니다. 참고할 수 있도록 모든 사람과 공유하세요. 자세한 내용은 다음과 같습니다.
최근 Mybatis
의 소스코드를 살펴보던 중 XML
구성 파일을 읽고 파싱하는 과정에서 발견한 내용은 다음과 같습니다. 빌더 모드가 사용되었습니다. 따라서 나는 이 디자인 패턴을 검토할 계획이다. Mybatis
的源码, 在阅读解析 XML
配置文件的过程中, 发现使用到了建造者(Builder)模式。 因此, 打算重温一下该设计模式。
假设我们需要画一个小人, 我们可能会有以下的构造函数定义:
public Person(HeadType headType, HairType hairType, HairColor hairColor, FaceType faceType, BodyType bodyType, ArmType amrType, LegType legTyype) { }
看到这么一个构造函数, 估计我们自己以后回来看的时候都懵了, 这么多参数, 导致我们后续的维护也很麻烦。
而构造模式就可以解决此类的问题。
目标是画一个小人
Builder
先定义抽象的PersonBuilder
。 该类定义了画小人需要的步骤, 这样每个通过PersonBuilder
产生的对象本质上就都是一样的了, 只不过个性上可以不一样。
abstract class PersonBuilder { protected Graphics graphics; public PersonBuilder(Graphics graphics) { this.graphics = graphics; } public abstract void buildHead(); public abstract void buildBody(); public abstract void buildArmLeft(); public abstract void buildArmRight(); public abstract void buildLegLeft(); public abstract void buildLegRight(); }
Builder
类在定义一个具体的实现类PersonFatBuilder
。 该类继承PersonBuilder
, 并实现了抽象方法。
public class PersonFatBuilder extends PersonBuilder { public PersonFatBuilder(Graphics graphics) { super(graphics); } @Override public void buildHead() { graphics.drawOval(50, 20, 30, 30); graphics.drawArc(50, 30, 10, 5, 45, 135); graphics.drawArc(70, 30, 10, 5, 45, 135); graphics.drawArc(60, 35, 10, 5, 200, 135); } @Override public void buildBody() { graphics.drawRect(55, 50, 20, 50); } @Override public void buildArmLeft() { graphics.drawLine(55, 50, 40, 100); } @Override public void buildArmRight() { graphics.drawLine(75, 50, 90, 100); } @Override public void buildLegLeft() { graphics.drawLine(55, 100, 45, 150); } @Override public void buildLegRight() { graphics.drawLine(75, 100, 85, 150); } }
Director
类该类负责具体的建造过程, 对建成什么样不关心。
public class PersonDirector { private PersonBuilder personBuilder; public PersonDirector(PersonBuilder personBuilder) { this.personBuilder = personBuilder; } public void drawPerson() { personBuilder.buildHead(); personBuilder.buildBody(); personBuilder.buildArmLeft(); personBuilder.buildArmRight(); personBuilder.buildLegLeft(); personBuilder.buildLegRight(); } }
建立一个窗口,将小人画出来。
public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { // 创建窗口对象 JFrame frame = new JFrame(); frame.setVisible(true); frame.setTitle("画人"); frame.setSize(250, 300); // 设置窗口关闭按钮的默认操作(点击关闭时退出进程) frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); // 把窗口位置设置到屏幕的中心 frame.setLocationRelativeTo(null); frame.setContentPane(new JPanel(){ @Override protected void paintComponent(Graphics g) { super.paintComponent(g); PersonThinBuilder thinBuilder = new PersonThinBuilder(g); PersonDirector director = new PersonDirector(thinBuilder); director.drawPerson(); } }); } }); }
结果如下:
将复杂对象的构建与它的表示分离, 使得同样的构建过程可以创建不同的表示。
换句话解释, 允许你创建不同种类的对象, 同时又能避免对构造函数的污染。当对象有多种类型时, 该模式非常有用。 或者在创建对象时涉及到很多的步骤。
引用《大话设计模式》的一个图
抽象类Builder
:为创建Product
对象而抽象的接口。
继承类ConcreateBuilder
:具体的建造者, 构造和装配各个部件。
具体产品类Product
:我们需要建造的对象。
Director
: 用来创建产品的, 其内部有Builder
类型的成员变量。
Director
不需要知道 Product
的内部细节, 它只提供需要的信息给建设者, 由具体的建造者ConcreateBuilder
处理从而完成产品的构造。
建造者模式将复杂的产品创建过程分散到了不同的对象中, 从而实现对产品创建过程更精确的控制, 创建过程更加清晰。
每个具体的建造者都可以创建出完整的产品对象, 而且是相互独立的。 因此, 调用端可以通过不同的具体建造者就可以得到不同的对象。当有新的产品出现时, 不需要改变原有代码, 只需要添加一个建造者即可。
现在如果我们想建造一个胖小人,有五官的。那我们只需要添加一个PersonFatBuilder
public class PersonFatBuilder extends PersonBuilder { public PersonFatBuilder(Graphics graphics) { super(graphics); } @Override public void buildHead() { graphics.drawOval(50, 20, 30, 30); graphics.drawArc(50, 30, 10, 5, 45, 135); graphics.drawArc(70, 30, 10, 5, 45, 135); graphics.drawArc(60, 35, 10, 5, 200, 135); } @Override public void buildBody() { graphics.drawRect(55, 50, 20, 50); } @Override public void buildArmLeft() { graphics.drawLine(55, 50, 40, 100); } @Override public void buildArmRight() { graphics.drawLine(75, 50, 90, 100); } @Override public void buildLegLeft() { graphics.drawLine(55, 100, 45, 150); } @Override public void buildLegRight() { graphics.drawLine(75, 100, 85, 150); } }그런 생성자를 보면, 다시 돌아와서 보면 혼란스러울 것 같습니다. 너무 많은 매개변수로 인해 후속 유지 관리가 매우 번거로워집니다.
구성 패턴은 이러한 문제를 해결할 수 있습니다.
목표는 작은 사람을 그리는 것입니다
Builder
PersonBuilder를 정의합니다. 코드>. 이 클래스는 악당을 그리는 데 필요한 단계를 정의하므로 <code>PersonBuilder
를 통해 생성된 각 개체는 기본적으로 동일하지만 성격이 다를 수 있습니다. rrreee
Builder
클래스 정의PersonFatBuilder
를 정의하세요. 이 클래스는 PersonBuilder
를 상속하고 추상 메서드를 구현합니다. rrreeeDirector
클래스를 정의합니다.rrreee
Builder
: Product
개체를 생성하기 위한 추상 인터페이스입니다. 🎜🎜상속 클래스 ConcreateBuilder
: 특정 빌더, 다양한 구성 요소를 구성 및 어셈블합니다. 🎜🎜특정 제품 카테고리 제품
: 빌드해야 하는 객체입니다. 🎜🎜Director
: 제품을 만드는 데 사용되며 내부에 Builder
유형의 멤버 변수가 있습니다. 🎜이사
는 제품
의 내부 세부정보를 알 필요가 없습니다. , 특정 빌더인 ConcreateBuilder
에서 처리하여 제품 구성을 완료하는 데 필요한 정보만 빌더에 제공합니다. 🎜PersonFatBuilder
클래스만 추가하면 되며 원본 코드를 변경할 필요가 없습니다. 🎜rrreee🎜결과:🎜🎜🎜🎜🎜관련 권장 사항:🎜🎜🎜🎜【oracle 튜토리얼】Oracle Warehouse Builder 11g Rel🎜🎜🎜🎜yii Query Builder(yii Query Builder) 공식 가이드 번역🎜🎜위 내용은 Java 디자인 패턴 - 빌더 패턴의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!