1 Visão Geral
O Builder Pattern (Builder Pattern) é usado principalmente para "construir um objeto complexo passo a passo", no qual "passo a passo" é um algoritmo estável, enquanto as várias partes do objeto complexo mudam frequentemente. Portanto, o padrão construtor é usado principalmente para resolver os requisitos variáveis da "parte do objeto". Isso permite um controle mais refinado sobre o processo de construção do objeto.
2 exemplos
Tomando como exemplo a produção de celulares, cada celular é dividido em Tela, CPU e Bateria. Agora existem dois tipos de celulares a serem produzidos, Apple e Samsung.
maçã:
Copie o código do código da seguinte forma:
pacoteorg.scott.builder.before.use;
importar java.util.ArrayList;
importar java.util.List;
/**
* @autor Scott
* @versão 20/11/2013
* @descrição
*/
classe pública ApplePhone {
List<String> partes = new ArrayList<String>();
public void criarCPU() {
parts.add("CUP: Qualcomm");
}
public void createScreen() {
parts.add("TELA: JDI");
}
public void criarBateria() {
parts.add("BATERIA: DeSai");
}
exibição pública vazia(){
System.out.print("Informações sobre componentes do produto:");
for(String parte: partes){
System.out.print(parte + "/t");
}
}
}
Samsung:
Copie o código do código da seguinte forma:
pacoteorg.scott.builder.before.use;
importar java.util.ArrayList;
importar java.util.List;
/**
* @autor Scott
* @versão 20/11/2013
* @descrição
*/
classe pública SamsungPhone {
List<String> partes = new ArrayList<String>();
public void criarCPU() {
peças.add("CUP: MTK");
}
public void createScreen() {
parts.add("TELA: Samsung");
}
public void criarBateria() {
parts.add("BATERIA: DeSai");
}
exibição pública vazia(){
System.out.print("Informações sobre componentes do produto:");
for(String parte: partes){
System.out.print(parte + "/t");
}
}
}
Cliente de teste:
Copie o código do código da seguinte forma:
pacoteorg.scott.builder.before.use;
/**
* @autor Scott
* @versão 20/11/2013
* @descrição
*/
classe pública BuilderTest {
privado estático ApplePhone iphone = novo ApplePhone();
private static SamsungPhone samPhone = novo SamsungPhone();
public static void main(String args[]){
iphone.createCPU();
iphone.createScreen();
iphone.createBattery();
iphone.show();
samPhone.createCPU();
samPhone.createScreen();
samPhone.createBattery();
samPhone.show();
}
}
Você encontrou um problema? Ou seja, todo processo de produção de telefones celulares é o mesmo. Para ser mais preciso, os nomes dos processos são os mesmos, mas o processamento específico de cada processo é diferente. processamento de cada mudança de processo, a partir disso podemos extrair o inalterado, "inalterado para lidar com todas as mudanças" e entregar a mudança para produtos específicos.
Como fazer isso especificamente? Desta vez, o modo Builder é útil.
Primeiro, vamos dar uma olhada na interface do telefone:
Copie o código do código da seguinte forma:
pacoteorg.scott.builder.after.use;
importar java.util.ArrayList;
importar java.util.List;
/**
* @autor Scott
* @versão 20/11/2013
* @descrição
*/
classe abstrata pública Telefone {
partes protegidas de List<String> = new ArrayList<String>();
public void add(parte da string){
peças.add(parte);
}
exibição pública vazia(){
System.out.print("Informações sobre componentes do produto:");
for(String parte: partes){
System.out.print(parte + "/t");
}
}
}
Categoria de celular Apple:
Copie o código do código da seguinte forma:
pacoteorg.scott.builder.after.use;
/**
* @autor Scott
* @versão 20/11/2013
* @descrição
*/
classe pública ApplePhone estende telefone{
}
Categoria de celular Samsung:
Copie o código do código da seguinte forma:
pacoteorg.scott.builder.after.use;
/**
* @autor Scott
* @versão 20/11/2013
* @descrição
*/
classe pública SamsungPhone estende telefone{
}
Em seguida, defina um construtor de interface para a etapa de produção:
Copie o código do código da seguinte forma:
pacoteorg.scott.builder.after.use;
/**
* @autor Scott
* @versão 20/11/2013
* @descrição
*/
Construtor de interface pública {
public void buildCPU();
public void buildScreen();
public void buildBattery();
telefone público getTelefone();
}
Construtor para iPhone:
Copie o código do código da seguinte forma:
pacoteorg.scott.builder.after.use;
/**
* @autor Scott
* @versão 20/11/2013
* @descrição
*/
classe pública ApplePhoneBuilder implementa Builder{
telefone privado telefone = novo ApplePhone();
@Substituir
public void buildCPU() {
phone.add("CUP: Qualcomm");
}
@Substituir
public void buildScreen() {
phone.add("TELA: JDI");
}
@Substituir
public void buildBattery() {
phone.add("BATERIA: DeSai");
}
@Substituir
telefone público getPhone() {
telefone de retorno;
}
}
Construtor para celulares Samsung:
Copie o código do código da seguinte forma:
pacoteorg.scott.builder.after.use;
/**
* @autor Scott
* @versão 20/11/2013
* @descrição
*/
classe pública SamsungPhoneBuilder implementa Builder{
telefone privado telefone = novo SamsungPhone();
@Substituir
public void buildCPU() {
phone.add("CUP: MTK");
}
@Substituir
public void buildScreen() {
phone.add("TELA: Samsung");
}
@Substituir
public void buildBattery() {
phone.add("BATERIA: DeSai");
}
@Substituir
telefone público getPhone() {
telefone de retorno;
}
}
Diretor que orienta a produção específica de celulares:
Copie o código do código da seguinte forma:
pacoteorg.scott.builder.after.use;
/**
* @autor Scott
* @versão 20/11/2013
* @descrição
*/
diretor de classe pública {
construtor construtor privado;
Diretor público(Construtor construtor){
this.builder = construtor;
}
construção pública vazia(){
construtor.buildCPU();
construtor.buildScreen();
construtor.buildBattery();
}
}
Finalmente escreva uma classe de teste:
Copie o código do código da seguinte forma:
pacoteorg.scott.builder.after.use;
/**
* @autor Scott
* @versão 20/11/2013
* @descrição
*/
classe pública BuilderTest {
construtor estático privado iPhoneBuilder = novo ApplePhoneBuilder();
Construtor estático privado samPhoneBuilder = novo SamsungPhoneBuilder();
public static void main(String[] args) {
Diretor diretor = novo Diretor(iPhoneBuilder);
diretor.construct();
Telefone telefone = iPhoneBuilder.getPhone();
System.out.println("iphone");
telefone.show();
diretor = novo Diretor(samPhoneBuilder);
diretor.construct();
telefone = samPhoneBuilder.getPhone();
System.out.println("/nsamSung");
telefone.show();
}
}
Resultados em execução:
Copie o código do código da seguinte forma:
iphone
Informações sobre a peça do produto: COPO: Qualcomm TELA: JDI BATERIA: DeSai
Samsung
Informações sobre a peça do produto: COPO: MTK TELA: Samsung BATERIA: DeSai
As duas classes de entidade Phone aqui estão vazias. Se for esse o caso, elas poderão ser omitidas. Se a interface Phone também puder ser omitida, apenas as classes de implementação Director, Builder e Builder específicas serão deixadas. Além disso, a classe ApplePhone e a classe SamsungPhone são duas classes relacionadas. Eles são marcas diferentes de telefones celulares. Se você encontrar duas ou mais classes que não estão muito relacionadas, não há necessidade de existir a interface pública Phone. , Então, como determinar o valor de retorno do método getPhone() especificado na interface do Builder?
Independentemente de o tipo de valor de retorno ser ApplePhone ou SamsungPhone, surgirão problemas porque os tipos de resultados retornados não são uniformes. Neste momento, Phone pode ser definido como uma interface vazia (uma interface que não contém nenhum método) e, em seguida, permitir que essas classes de produtos específicas que não têm relacionamento entre si implementem essa interface. Em seguida, o tipo de valor de retorno de getPhone(. ) método especificado na interface do Builder Ainda é um tipo de telefone, o que resolve o problema. Porém, neste caso, não há necessidade de usar o modo Builder.