Compartilhamento de tecnologia

Padrão de design padrão de fábrica

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Factory Pattern é um padrão de design comumente usado em programação orientada a objetos.padrão criacional tipo de.O padrão de fábrica é usado principalmente para criar objetos, mas é diferente de usá-lo diretamente no código.new A criação de palavras-chave é diferente porque cria objetos por meio de uma interface comum, separando assim o processo de criação de objetos do uso do código do cliente. A seguir está uma introdução detalhada ao padrão de fábrica:

1. Principais características do modelo de fábrica

  1. O processo de criação de objetos encapsulados: Encapsular o processo de criação do objeto em uma classe de fábrica, o cliente só precisa especificar o tipo de objeto que precisa ser criado e então pode obter o objeto necessário por meio da classe de fábrica sem se preocupar com os detalhes específicos de criação do objeto.
  2. Reduzir o acoplamento: Ao isolar a fábrica abstrata e a fábrica concreta, o acoplamento entre o cliente e o objeto é reduzido, tornando o programa cliente mais fácil de expandir e manter.
  3. Melhore a escalabilidade do programa: Quando você precisa adicionar um novo produto, você só precisa adicionar a classe de produto específica correspondente e a classe de fábrica correspondente. Não há necessidade de modificar o código original. Ele está em conformidade com o princípio de abertura e fechamento (aberto para expansão e fechado). para modificação), o que melhora a escalabilidade do código.
  4. Fácil de manter e atualizar: Como o método de fábrica concentra o processo de criação de objetos em uma classe, se você precisar modificar o método de criação de objetos, basta modificar a classe de fábrica correspondente, o que não terá impacto no cliente.
  5. reutilização de código: O padrão de fábrica pode abstrair o processo de criação de objetos, realizar a reutilização de código e aumentar a flexibilidade e reutilização do código.

2. Classificação do modelo de fábrica

Os padrões de fábrica são divididos principalmente em três tipos: padrão de fábrica simples (padrão de fábrica estático), padrão de método de fábrica e padrão de fábrica abstrato.

1. Método de fábrica estático
  1. Defina uma classe de fábrica para retornar instâncias de diferentes classes com base nos diferentes parâmetros passados.
  2. As classes de fábrica geralmente contêm vários métodos estáticos, cada método correspondendo à criação de um produto específico.
  3. Vantagens: Simples de implementar e fácil de entender.
  4. Desvantagens: As responsabilidades da classe fábrica são muito pesadas. Ao adicionar novos produtos, o código-fonte da classe fábrica precisa ser modificado, o que viola o princípio de abertura e fechamento.

Diagrama de classes de padrão de fábrica simples

2. Padrão de Método de Fábrica (Método de Fábrica)
  1. Definir uma interface (fábrica abstrata) para criação de objetos,Mas deixe a subclasse decidir qual classe instanciar
  2. Os métodos de fábrica permitem que a instanciação de classes seja adiada para subclasses.
  3. Vantagens: Boa escalabilidade Quando novos produtos precisam ser adicionados, apenas as categorias específicas de produtos e categorias específicas de fábrica correspondentes precisam ser adicionadas.
  4. Desvantagens: Cada vez que um produto é adicionado, uma classe específica e uma fábrica de implementação de objetos precisam ser adicionadas, dobrando o número de classes no sistema e aumentando a complexidade do sistema.

Padrão de método de fábrica

3. Padrão de fábrica abstrata (fábrica abstrata)
  1. Fornece uma interface para criar uma série de objetos relacionados ou interdependentes sem especificar suas classes concretas.
  2. O padrão abstrato de fábrica pode ser visto como o uso conjunto de vários padrões de método de fábrica.
  3. Vantagens: A família de produtos pode ser restrita dentro da classe. Uma fábrica específica deve ser capaz de criar todos os produtos da família de produtos.
  4. Desvantagens: Aumenta a abstração e a dificuldade de compreensão do sistema, e o número de classes no sistema aumentará significativamente.

padrão de fábrica abstrato

3. Cenários de aplicação do modelo de fábrica

O padrão de fábrica tem uma ampla gama de aplicações no desenvolvimento real, como conexões de banco de dados, controles de UI, processamento de arquivos, registro, comunicações de rede, filas de mensagens, estruturas de dados, criptografia e descriptografia, envio de mensagens e agendamento de tarefas. Nestes cenários, a utilização do padrão de fábrica pode separar o processo de criação de objetos do processo de utilização, melhorando a flexibilidade e escalabilidade do sistema.

4. Exemplo de modelo de fábrica

1. Exemplo simples de padrão de fábrica

No padrão de fábrica simples, definimos uma classe de fábrica que pode retornar instâncias de diferentes tipos com base nos parâmetros passados.

Abaixo está um exemplo de um padrão de fábrica simples escrito em Java. Criaremos uma fábrica de formas que pode produzir instâncias de círculos, retângulos e quadrados. Primeiro, definimos uma interface de forma (Shape) e diversas classes concretas (Circle, Rectangle, Square) que implementam esta interface.

  1. // 形状接口
  2. interface Shape {
  3. void draw();
  4. }
  5. // 圆形类
  6. class Circle implements Shape {
  7. @Override
  8. public void draw() {
  9. System.out.println("Inside Circle::draw() method.");
  10. }
  11. }
  12. // 矩形类
  13. class Rectangle implements Shape {
  14. @Override
  15. public void draw() {
  16. System.out.println("Inside Rectangle::draw() method.");
  17. }
  18. }
  19. // 正方形类
  20. class Square implements Shape {
  21. @Override
  22. public void draw() {
  23. System.out.println("Inside Square::draw() method.");
  24. }
  25. }

A seguir, definimos uma classe de fábrica (ShapeFactory) que utiliza métodos estáticos para gerar objetos de forma.

  1. // 形状工厂类
  2. class ShapeFactory {
  3. // 使用 getShape 方法获取形状类型的对象
  4. public static Shape getShape(String shapeType){
  5. if(shapeType == null){
  6. return null;
  7. }
  8. if(shapeType.equalsIgnoreCase("CIRCLE")){
  9. return new Circle();
  10. } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
  11. return new Rectangle();
  12. } else if(shapeType.equalsIgnoreCase("SQUARE")){
  13. return new Square();
  14. }
  15. return null;
  16. }
  17. }

Finalmente, podemos usar uma classe de fábrica para obter objetos de forma e chamar seusdrawmétodo.

  1. public class FactoryPatternDemo {
  2. public static void main(String[] args) {
  3. // 获取 Circle 的对象,并调用它的 draw 方法
  4. Shape shape1 = ShapeFactory.getShape("CIRCLE");
  5. shape1.draw();
  6. // 获取 Rectangle 的对象,并调用它的 draw 方法
  7. Shape shape2 = ShapeFactory.getShape("RECTANGLE");
  8. shape2.draw();
  9. // 获取 Square 的对象,并调用它的 draw 方法
  10. Shape shape3 = ShapeFactory.getShape("SQUARE");
  11. shape3.draw();
  12. }
  13. }

Neste exemplo,ShapeFactoryclasse é responsável por criarShape Uma instância da interface.O código do cliente faz isso passando informações de tipo (por exemplo, string) paraShapeFactorymétodo estático da classegetShape para obter uma instância da forma desejada. Desta forma, o cliente fica desacoplado da implementação da classe específica e atende ao princípio de abertura e fechamento, ou seja, novas classes de shape podem ser estendidas sem modificar o código do cliente. No entanto, uma grande desvantagem do padrão de fábrica simples é que se o sistema precisar ser ampliado com novas famílias de produtos (como cores além de formas, etc.), a classe de fábrica precisará ser modificada, o que viola parte do padrão aberto. -princípio fechado. Nesse caso, considere usar o padrão Factory Method ou o padrão Abstract Factory.

2. Exemplo de padrão de método de fábrica

Ainda tomando forma como exemplo, utilizamos métodos de engenharia para criá-lo.

Primeiro defina a interface de forma (Produto) e crie três classes de implementação.

  1. // 形状接口
  2. interface Shape {
  3. void draw();
  4. }
  5. // 圆形类
  6. class Circle implements Shape {
  7. @Override
  8. public void draw() {
  9. System.out.println("Inside Circle::draw() method.");
  10. }
  11. }
  12. // 矩形类
  13. class Rectangle implements Shape {
  14. @Override
  15. public void draw() {
  16. System.out.println("Inside Rectangle::draw() method.");
  17. }
  18. }
  19. // 正方形类
  20. class Square implements Shape {
  21. @Override
  22. public void draw() {
  23. System.out.println("Inside Square::draw() method.");
  24. }
  25. }

A seguir, defina a interface do criador (Creator) e o criador concreto (Concrete Creator):

  1. // 创建者接口
  2. interface ShapeFactory {
  3. Shape getShape(String shapeType);
  4. }
  5. // 具体创建者类
  6. class RectangleFactory implements ShapeFactory {
  7. @Override
  8. public Shape getShape(String shapeType) {
  9. if (shapeType == null) {
  10. return null;
  11. }
  12. if (shapeType.equalsIgnoreCase("RECTANGLE")) {
  13. return new Rectangle();
  14. }
  15. return null;
  16. }
  17. }
  18. class CircleFactory implements ShapeFactory {
  19. @Override
  20. public Shape getShape(String shapeType) {
  21. if (shapeType == null) {
  22. return null;
  23. }
  24. if (shapeType.equalsIgnoreCase("CIRCLE")) {
  25. return new Circle();
  26. }
  27. return null;
  28. }
  29. }
  30. class SquareFactory implements ShapeFactory {
  31. @Override
  32. public Shape getShape(String shapeType) {
  33. if (shapeType == null) {
  34. return null;
  35. }
  36. if (shapeType.equalsIgnoreCase("SQUARE")) {
  37. return new Square();
  38. }
  39. return null;
  40. }
  41. }

Finalmente, use a classe criadora concreta para obter os objetos de forma e chamar seusdrawmétodo:

  1. public class FactoryMethodPatternDemo {
  2. public static void main(String[] args) {
  3. ShapeFactory shapeFactory = new CircleFactory();
  4. // 获取 Circle 的对象,并调用它的 draw 方法
  5. Shape shape1 = shapeFactory.getShape("CIRCLE");
  6. shape1.draw();
  7. // 使用 RectangleFactory 来获取 Rectangle 的对象
  8. shapeFactory = new RectangleFactory();
  9. Shape shape2 = shapeFactory.getShape("RECTANGLE");
  10. shape2.draw();
  11. // 使用 SquareFactory 来获取 Square 的对象
  12. shapeFactory = new SquareFactory();
  13. Shape shape3 = shapeFactory.getShape("SQUARE");
  14. shape3.draw();
  15. }
  16. }

Neste exemplo,Criamos uma classe de fábrica correspondente para cada classe de forma (Embora em aplicações reais, geralmente haja uma estrutura de classes de fábrica mais geral, talvez por meio de arquivos de configuração ou reflexão para evitar escrever classes de fábrica separadas para cada classe de produto). Isso ajuda a demonstrar os fundamentos do padrão Factory Method,Ou seja, deixe a subclasse de fábrica decidir qual classe instanciar . No entanto, para o caso simples deste exemplo, você pode estar mais inclinado a usar o padrão Simple Factory ou considerar outros padrões de design para reduzir a duplicação de código.

3. Exemplo abstrato de fábrica

Este exemplo toma como exemplo telefones celulares, produtos abstratos relacionados a telefones celulares (como telas, baterias, sistemas operacionais, etc.) e cria classes de produtos específicas para implementar essas interfaces. Podemos então definir interfaces de fábrica abstratas e classes de fábrica concretas para produzir esses produtos. Aqui está um exemplo simplificado que mostra como usar o padrão Abstract Factory para produzir componentes (telas e baterias) para diferentes marcas e modelos de telefones celulares:

Primeiro, defina a interface do produto e produtos específicos:

  1. // 屏幕接口
  2. interface Screen {
  3. void display();
  4. }
  5. // 高端屏幕的实现
  6. class HighEndScreen implements Screen {
  7. @Override
  8. public void display() {
  9. System.out.println("显示高清屏幕");
  10. }
  11. }
  12. // 低端屏幕的实现
  13. class LowEndScreen implements Screen {
  14. @Override
  15. public void display() {
  16. System.out.println("显示普通屏幕");
  17. }
  18. }
  19. // 电池接口
  20. interface Battery {
  21. void charge();
  22. }
  23. // 高效电池的实现
  24. class HighEfficiencyBattery implements Battery {
  25. @Override
  26. public void charge() {
  27. System.out.println("快速充电");
  28. }
  29. }
  30. // 标准电池的实现
  31. class StandardBattery implements Battery {
  32. @Override
  33. public void charge() {
  34. System.out.println("标准充电");
  35. }
  36. }

A seguir, defina a interface de fábrica abstrata e a classe de fábrica concreta:

  1. // 手机组件工厂接口
  2. interface PhoneFactory {
  3. Screen createScreen();
  4. Battery createBattery();
  5. }
  6. // 高端手机工厂
  7. class HighEndPhoneFactory implements PhoneFactory {
  8. @Override
  9. public Screen createScreen() {
  10. return new HighEndScreen();
  11. }
  12. @Override
  13. public Battery createBattery() {
  14. return new HighEfficiencyBattery();
  15. }
  16. }
  17. // 低端手机工厂
  18. class LowEndPhoneFactory implements PhoneFactory {
  19. @Override
  20. public Screen createScreen() {
  21. return new LowEndScreen();
  22. }
  23. @Override
  24. public Battery createBattery() {
  25. return new StandardBattery();
  26. }
  27. }

Finalmente, o código do cliente, que usa uma fábrica abstrata para criar objetos de produto concretos:

  1. public class PhoneFactoryPatternDemo {
  2. public static void main(String[] args) {
  3. // 使用高端手机工厂
  4. PhoneFactory highEndFactory = new HighEndPhoneFactory();
  5. Screen highEndScreen = highEndFactory.createScreen();
  6. Battery highEndBattery = highEndFactory.createBattery();
  7. highEndScreen.display();
  8. highEndBattery.charge();
  9. // 使用低端手机工厂
  10. PhoneFactory lowEndFactory = new LowEndPhoneFactory();
  11. Screen lowEndScreen = lowEndFactory.createScreen();
  12. Battery lowEndBattery = lowEndFactory.createBattery();
  13. lowEndScreen.display();
  14. lowEndBattery.charge();
  15. }
  16. }

Neste exemplo, definimos duas fábricas de telefones celulares (alta e baixa), cada uma capaz de produzir um tipo específico de tela e bateria.O código do cliente interage com a classe de fábrica específica por meio da interface abstrata de fábrica, conseguindo assim o desacoplamento da classe de produto específica. . Desta forma, se precisarmos adicionar novos tipos de telefone no futuro (por exemplo, telefones de gama média), só precisaremos adicionar novas classes de produtos e classes de fábrica correspondentes sem modificar o código do cliente existente.

5. Resumo

O padrão de fábrica é um padrão de design muito útil,Ele encapsula o processo de criação de objetos, reduz o acoplamento, melhora a escalabilidade do programa e a facilidade de manutenção, etc. , tem sido amplamente utilizado no desenvolvimento de software.No entanto, também tem algunsDesvantagens, como responsabilidades excessivas de fábrica, dificuldade de expansão do sistema, etc. . Portanto, em aplicações práticas, é necessário fazer compromissos e escolhas com base em cenários e necessidades específicas.

Se o padrão de fábrica (fábrica simples, método de fábrica, fábrica abstrata) for útil para você, lembre-se de gostar e colecioná-lo.