> Java > java지도 시간 > Java 팩토리 패턴 예제 코드 분석

Java 팩토리 패턴 예제 코드 분석

WBOY
풀어 주다: 2023-04-14 19:16:13
앞으로
1220명이 탐색했습니다.

간단한 공장 모델

특정 요구 사항을 살펴보세요

피자 프로젝트를 살펴보세요. 피자 종류를 확장하고 유지 관리가 쉬워야 합니다.

1) 피자 종류가 많습니다(GreekPizz, CheesePizz 등). 등)

2 ) 피자 만들기에는 준비, 굽기, 자르기, 상자

3) 피자 가게 주문 기능이 포함됩니다.

package com.example.demo.simplefactory.pizzastore.pizza;

/**
 * 将Pizza 类做成抽象
 * @author Administrator
 *
 */
public abstract class Pizza {
  /**
   * 名字
   */
  protected String name;
  
  /**
   * 准备原材料,不同的披萨不一样,因此,我们做成抽象方法
   */
  public abstract void prepare();
  
  public void bake() {
    System.out.println(name + " baking;");
  }
  
  public void cut() {
    System.out.println(name + " cutting;");
  }
  
  public void box() {
    System.out.println(name + " boxing");
  }
  
  public void setName(String name) {
    this.name = name;
  }
  
}
package com.example.demo.simplefactory.pizzastore.pizza;

public class GreekPizza extends Pizza{

  @Override
  public void prepare() {
    System.out.println(" 给希腊披萨 准备原材料");
  }

}
package com.example.demo.simplefactory.pizzastore.pizza;

public class CheesePizza extends Pizza{

  @Override
  public void prepare() {
    System.out.println(" 给制作奶酪披萨,准备原材料");
  }

}
package com.example.demo.simplefactory.pizzastore.order;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import com.example.demo.simplefactory.pizzastore.pizza.CheesePizza;
import com.example.demo.simplefactory.pizzastore.pizza.GreekPizza;
import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class OrderPizza {
  
  /**
   * 构造器
   */
  public OrderPizza() {
    Pizza pizza = null;
    // 订购披萨的类型
    String orderType;
    do {
      orderType = getType();
      if (orderType.equals("greek")) {
        pizza = new GreekPizza();
        pizza.setName(" 希腊披萨 ");
      } else if (orderType.equals("cheese")) {
        pizza = new CheesePizza();
        pizza.setName(" 奶酪披萨 ");
      } else {
        break;
      }
      // 输出pizza 制作过程
      pizza.prepare();
      pizza.bake();
      pizza.cut();
      pizza.box();
    } while (true);
  }
  
  /**
   * 写一个方法,可以获取客户希望订购的披萨种类
   * @return
   */
  private String getType() {
    try {
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
      System.out.println("input pizza type : ");
      String string = bufferedReader.readLine();
      return string;
    } catch(IOException e) {
      e.printStackTrace();
      return "";
    }
  }
}
package com.example.demo.simplefactory.pizzastore.order;

/**
 * 相当于一个客户端,发出订购
 * @author Administrator
 *
 */
public class PizzaStore {

  public static void main(String[] args) {
    new OrderPizza();
  }

}
로그인 후 복사

전통 방식의 장점과 단점:

1) 이해하기 쉽고 조작하기 쉽다는 장점이 있습니다.

2) 단점은 확장에는 개방적이고 수정에는 폐쇄라는 디자인 패턴의 OCP 원칙을 위반한다는 점입니다. 즉, 클래스에 새 함수를 추가할 때 코드를 수정하지 않거나 코드를 가능한 한 적게 수정하려고 노력하는 것입니다.

3) 예를 들어 이때 새로운 피자 종류를 추가하려면 다음과 같이 수정해야 합니다.

package com.example.demo.simplefactory.pizzastore.pizza;

public class PepperPizza extends Pizza{

  @Override
  public void prepare() {
    System.out.println(" 给胡椒披萨准备原材料 ");
  }

}
package com.example.demo.simplefactory.pizzastore.order;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import com.example.demo.simplefactory.pizzastore.pizza.CheesePizza;
import com.example.demo.simplefactory.pizzastore.pizza.GreekPizza;
import com.example.demo.simplefactory.pizzastore.pizza.PepperPizza;
import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class OrderPizza {
  
  /**
   * 构造器
   */
  public OrderPizza() {
    Pizza pizza = null;
    // 订购披萨的类型
    String orderType;
    do {
      orderType = getType();
      if (orderType.equals("greek")) {
        pizza = new GreekPizza();
        pizza.setName(" 希腊披萨 ");
      } else if (orderType.equals("cheese")) {
        pizza = new CheesePizza();
        pizza.setName(" 奶酪披萨 ");
      } else if (orderType.equals("pepper")) {
        pizza = new PepperPizza();
        pizza.setName("胡椒披萨");
      } else {
        break;
      }
      // 输出pizza 制作过程
      pizza.prepare();
      pizza.bake();
      pizza.cut();
      pizza.box();
    } while (true);
  }
  
  /**
   * 写一个方法,可以获取客户希望订购的披萨种类
   * @return
   */
  private String getType() {
    try {
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
      System.out.println("input pizza type : ");
      String string = bufferedReader.readLine();
      return string;
    } catch(IOException e) {
      e.printStackTrace();
      return "";
    }
  }
}
로그인 후 복사

4) 아이디어 분석 개선
분석: 코드 수정은 허용되지만, 다른 곳에 피자를 생성하는 코드도 있다면 그 코드도 수정해야 한다는 뜻이고, 피자를 생성하는 코드에는 여러 개가 있는 경우가 많습니다. 장소.
아이디어: Pizza 객체 생성을 클래스로 캡슐화하여 새로운 피자 유형이 있을 때 클래스만 수정하면 되고 Pizza 객체를 생성하는 다른 코드는 수정할 필요가 없도록 합니다.

간단한 팩토리 패턴

기본 소개

1) 심플팩토리 패턴은 창작 패턴이자 팩토리 패턴의 일종이다. 단순 팩토리 패턴은 팩토리 객체를 사용하여 생성할 제품 클래스 인스턴스를 결정합니다. 심플 팩토리 패턴은 팩토리 패턴 계열 중에서 가장 간단하고 실용적인 패턴입니다

2) 심플 팩토리 패턴: 객체를 생성하는 클래스를 정의하고, 이 클래스는 객체를 인스턴스화하는 라인(코드)을 캡슐화합니다

3) 소프트웨어 개발에서 특정 유형, 유형 또는 배치의 객체를 대량 생성할 때 팩토리 패턴을 사용합니다.

package com.example.demo.simplefactory.pizzastore.order;

import com.example.demo.simplefactory.pizzastore.pizza.CheesePizza;
import com.example.demo.simplefactory.pizzastore.pizza.GreekPizza;
import com.example.demo.simplefactory.pizzastore.pizza.PepperPizza;
import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

/**
 * 简单工厂类
 * @author Administrator
 *
 */
public class SimpleFactory {

  public Pizza createPizza(String orderType) {
    Pizza pizza = null;
    System.out.println("使用简单工厂模式");
    if (orderType.equals("greek")) {
      pizza = new GreekPizza();
      pizza.setName(" 希腊披萨 ");
    } else if (orderType.equals("cheese")) {
      pizza = new CheesePizza();
      pizza.setName(" 奶酪披萨 ");
    } else if (orderType.equals("pepper")) {
      pizza = new PepperPizza();
      pizza.setName("胡椒披萨");
    } 
    return pizza;
  }
  
}
package com.example.demo.simplefactory.pizzastore.order;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import com.example.demo.simplefactory.pizzastore.pizza.CheesePizza;
import com.example.demo.simplefactory.pizzastore.pizza.GreekPizza;
import com.example.demo.simplefactory.pizzastore.pizza.PepperPizza;
import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class OrderPizza {
  
  /**
   * 构造器
   */
  /*
   * public OrderPizza() { Pizza pizza = null; // 订购披萨的类型 String orderType; do {
   * orderType = getType(); if (orderType.equals("greek")) { pizza = new
   * GreekPizza(); pizza.setName(" 希腊披萨 "); } else if (orderType.equals("cheese"))
   * { pizza = new CheesePizza(); pizza.setName(" 奶酪披萨 "); } else if
   * (orderType.equals("pepper")) { pizza = new PepperPizza();
   * pizza.setName("胡椒披萨"); } else { break; } // 输出pizza 制作过程 pizza.prepare();
   * pizza.bake(); pizza.cut(); pizza.box(); } while (true); }
   */
  
  /**
   * 构造器
   * @param simpleFactory
   */
  public OrderPizza(SimpleFactory simpleFactory) {
    setFactory(simpleFactory);
  }
  
  /**
   * 定义一个简单工厂对象
   */
  private SimpleFactory simpleFactory;
  private Pizza pizza = null;
  private void setFactory(SimpleFactory simpleFactory) {
    // 用户输入的
    String orderTypeString = "";
    // 设置简单工厂对象
    this.simpleFactory = simpleFactory;
    do {
      orderTypeString = getType();
      pizza = this.simpleFactory.createPizza(orderTypeString);
      // 输出pizza
      // 订购成功
      if (pizza != null) {
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
      } else {
        System.out.println(" 订购披萨失败 ");
        break;
      }
    } while (true);
  }
  
  /**
   * 写一个方法,可以获取客户希望订购的披萨种类
   * @return
   */
  private String getType() {
    try {
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
      System.out.println("input pizza type : ");
      String string = bufferedReader.readLine();
      return string;
    } catch(IOException e) {
      e.printStackTrace();
      return "";
    }
  }
}
package com.example.demo.simplefactory.pizzastore.order;

/**
 * 相当于一个客户端,发出订购
 * @author Administrator
 *
 */
public class PizzaStore {

  public static void main(String[] args) {
    //new OrderPizza();
    
    // 使用简单工厂模式
    new OrderPizza(new SimpleFactory());
    System.out.println("~~退出程序~~");
  }

}
로그인 후 복사

Factory 메소드 패턴

새로운 요구사항 살펴보기

피자 프로젝트의 새로운 요구사항: 고객이 피자를 주문할 때 베이징 치즈 피자, 베이징 페퍼 피자 또는 런던 피자 치즈와 같은 다양한 맛의 피자를 주문할 수 있습니다. 피자, 런던 페퍼 피자.

아이디어 1

간단한 팩토리 패턴을 사용하여 BJPizzaSimpleFactory, LDPizzaSimpleFactory 등과 같은 다양한 간단한 팩토리 클래스를 생성합니다. 현재의 경우에도 가능하지만 프로젝트 규모와 타당성을 고려하면 소프트웨어 유지 관리 및 확장성이 특별히 좋지 않습니다

아이디어 2

팩토리 메소드 패턴을 사용하세요

팩토리 메소드 패턴 소개

팩토리 메소드 패턴 설계 계획: 피자 프로젝트의 인스턴스화 기능 추상화 특히 서로 다른 플레이버 순서 하위 클래스에서 구현되는 추상 메소드로 변환됩니다.

Factory 메소드 패턴: 객체 생성을 위한 추상 메소드를 정의하고, 서브클래스는 인스턴스화할 클래스를 결정합니다. 팩토리 메소드 패턴은 객체의 인스턴스화를 하위 클래스 로 연기합니다.

package com.example.demo.factorymethod.pizzastore.order;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import com.example.demo.simplefactory.pizzastore.pizza.Pizza;
import com.fasterxml.jackson.databind.deser.ValueInstantiator.Gettable;

public abstract class OrderPizza {
  
  public OrderPizza() {
    Pizza pizza = null;
    // 订购披萨的类型
    String orderType;
    do {
      orderType = getType();
      createPizza(orderType);
      // 输出Pizza 制作过程
      pizza.prepare();
      pizza.bake();
      pizza.cut();
      pizza.box();
    } while (true);
  }
  
  /**
   * 定义一个抽象方法,createPizza,让各个工厂子类自己实现
   * @param orderType
   * @return
   */
  abstract Pizza createPizza(String orderType);
  
  /**
   * 写一个方法,可以获取客户希望订购的披萨种类
   * @return
   */
  private String getType() {
    try {
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
      System.out.println("input pizza type : ");
      String string = bufferedReader.readLine();
      return string;
    } catch(IOException e) {
      e.printStackTrace();
      return "";
    }
  }
}
package com.example.demo.factorymethod.pizzastore.order;

import org.apache.tomcat.util.security.Escape;

import com.example.demo.factorymethod.pizzastore.pizza.LDCheesePizza;
import com.example.demo.factorymethod.pizzastore.pizza.LDPepperPizza;
import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class LDOrderPizza extends OrderPizza{

  @Override
  Pizza createPizza(String orderType) {
    Pizza pizza = null;
    if (orderType.equals("cheese")) {
      pizza = new LDCheesePizza();
    } else if (orderType.equals("pepper")) {
      pizza = new LDPepperPizza();
    }
    return pizza;
  }

}
package com.example.demo.factorymethod.pizzastore.order;

import com.example.demo.factorymethod.pizzastore.pizza.BJCheesPizza;
import com.example.demo.factorymethod.pizzastore.pizza.BJPepperPizza;
import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class BJOrderPizza extends OrderPizza{

  @Override
  Pizza createPizza(String orderType) {
    Pizza pizza = null;
    if (orderType.equals("cheese")) {
      pizza = new BJCheesPizza();
    } else if (orderType.equals("pepper")) {
      pizza = new BJPepperPizza();
    }
    return pizza;
  }

}
package com.example.demo.factorymethod.pizzastore.pizza;

import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class BJCheesPizza extends Pizza{

  @Override
  public void prepare() {
    setName("北京的奶酪pizza");
    System.out.println(" 北京的奶酪pizza 准备原材料 ");
  }

}
package com.example.demo.factorymethod.pizzastore.pizza;

import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class BJPepperPizza extends Pizza{

  @Override
  public void prepare() {
    setName(" 北京的胡椒pizza ");
    System.out.println(" 北京的胡椒pizza 准备原材料  ");
  }

}
package com.example.demo.factorymethod.pizzastore.pizza;

import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class LDCheesePizza extends Pizza{

  @Override
  public void prepare() {
    setName(" 伦敦的奶酪pizza ");
    System.out.println(" 伦敦的奶酪pizza 准备原材料 ");
  }

}
package com.example.demo.factorymethod.pizzastore.pizza;

import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class LDPepperPizza extends Pizza{

  @Override
  public void prepare() {
    setName(" 伦敦的胡椒pizza ");
    System.out.println(" 伦敦的胡椒pizza 准备原材料 ");
  }

}
package com.example.demo.factorymethod.pizzastore.order;

public class PizzaStore {

  public static void main(String[] args) {
    // 创建北京口味的各种Pizza
    new BJOrderPizza();
  }

}
로그인 후 복사

추상 팩토리 패턴

기본 소개

1) 추상 팩토리 패턴: 특정 클래스를 지정하지 않고 관련 또는 종속 개체 클러스터를 만드는 데 사용되는 인터페이스를 정의합니다.

2) 추상 팩토리 패턴 Simple Factory를 통합할 수 있습니다. PatternFactory Method Pattern

3) 디자인 수준에서 추상 팩토리 패턴은 단순 팩토리 패턴의 개선(또는 추가 추상화)입니다.

4) 팩토리를 AbsFactory(추상 팩토리)와 구체적으로 구현된 팩토리 하위 클래스라는 두 개의 레이어로 추상화합니다. 프로그래머는 자신이 만드는 객체 유형에 따라 해당 팩토리 하위 클래스를 사용할 수 있습니다. 이는 단일 간단한 팩토리 클래스를 팩토리 클러스터로 전환하여 코드 유지 관리 및 확장에 더 도움이 됩니다.

package com.example.demo.absfactory.pizzastore.order;

import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

/**
 * 一个抽象工厂模式的抽象层(接口)
 * @author Administrator
 *
 */
public interface AbsFactory {
  
  /**
   * 让下面的工厂子类来   具体实现
   * @param orderType
   * @return
   */
  Pizza createPizza(String orderType);
}
package com.example.demo.absfactory.pizzastore.order;

import com.example.demo.absfactory.pizzastore.pizza.BJCheesPizza;
import com.example.demo.factorymethod.pizzastore.pizza.BJPepperPizza;
import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

/**
 * 这是工厂子类
 * @author Administrator
 *
 */
public class BJFactory implements AbsFactory{

  @Override
  public Pizza createPizza(String orderType) {
    System.out.println("~使用的是抽象工厂模式~");
    Pizza pizza = null;
    if (orderType.equals("cheese")) {
      pizza = new BJCheesPizza();
    } else if (orderType.equals("pepper") ) {
      pizza = new BJPepperPizza();
    }
    return pizza;
  }

}
package com.example.demo.absfactory.pizzastore.order;

import com.example.demo.absfactory.pizzastore.pizza.LDCheesePizza;
import com.example.demo.absfactory.pizzastore.pizza.LDPepperPizza;
import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class LDFactory implements AbsFactory{

  @Override
  public Pizza createPizza(String orderType) {
    System.out.println("~使用的是抽象工厂模式~");
    Pizza pizza = null;
    if (orderType.equals("cheese")) {
      pizza = new LDCheesePizza();
    } else if (orderType.equals("pepper")) {
      pizza = new LDPepperPizza();
    }
    return pizza;
  }

}
package com.example.demo.absfactory.pizzastore.order;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class OrderPizza {
  
  private AbsFactory factory;
  
  /**
   * 构造器
   * @param factory
   */
  public OrderPizza(AbsFactory factory) {
    setFactory(factory);
  }
  
  private void setFactory(AbsFactory factory) {
    Pizza pizza = null;
    // 用户输入
    String orderTypeString = "";
    this.factory = factory;
    do {
      orderTypeString = getType();
      pizza = factory.createPizza(orderTypeString);
      if (pizza != null) {
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
      } else {
        System.out.println("~订购失败~");
        break;
      }
    } while (true);
  }

  /**
   * 写一个方法,可以获取客户希望订购的披萨种类
   * @return
   */
  private String getType() {
    try {
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
      System.out.println("input pizza type : ");
      String string = bufferedReader.readLine();
      return string;
    } catch(IOException e) {
      e.printStackTrace();
      return "";
    }
  }
}
package com.example.demo.absfactory.pizzastore.pizza;

import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class BJCheesPizza extends Pizza{

  @Override
  public void prepare() {
    setName("北京的奶酪pizza");
    System.out.println(" 北京的奶酪pizza 准备原材料 ");
  }

}
package com.example.demo.absfactory.pizzastore.pizza;

import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class BJPepperPizza extends Pizza{

  @Override
  public void prepare() {
    setName(" 北京的胡椒pizza ");
    System.out.println(" 北京的胡椒pizza 准备原材料  ");
  }

}
package com.example.demo.absfactory.pizzastore.pizza;

import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class LDCheesePizza extends Pizza{

  @Override
  public void prepare() {
    setName(" 伦敦的奶酪pizza ");
    System.out.println(" 伦敦的奶酪pizza 准备原材料 ");
  }

}
package com.example.demo.absfactory.pizzastore.pizza;

import com.example.demo.simplefactory.pizzastore.pizza.Pizza;

public class LDPepperPizza extends Pizza{

  @Override
  public void prepare() {
    setName(" 伦敦的胡椒pizza ");
    System.out.println(" 伦敦的胡椒pizza 准备原材料 ");
  }

}
package com.example.demo.absfactory.pizzastore.order;

public class PizzaStore {
  public static void main(String[] args) {
    new OrderPizza(new BJFactory());
  }
}
로그인 후 복사

JDK의 팩토리 패턴-Calendar 애플리케이션 소스 코드 분석
1) JDK의 Calendar 클래스에서는 간단한 팩토리 패턴을 사용합니다

public static Calendar getInstance()
    {
        return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
    }
private static Calendar createCalendar(TimeZone zone,
                                           Locale aLocale)
    {
        CalendarProvider provider =
            LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale)
                                 .getCalendarProvider();
        if (provider != null) {
            try {
                return provider.getInstance(zone, aLocale);
            } catch (IllegalArgumentException iae) {
                // fall back to the default instantiation
            }
        }

        Calendar cal = null;

        if (aLocale.hasExtensions()) {
            String caltype = aLocale.getUnicodeLocaleType("ca");
            if (caltype != null) {
                switch (caltype) {
                case "buddhist":
                cal = new BuddhistCalendar(zone, aLocale);
                    break;
                case "japanese":
                    cal = new JapaneseImperialCalendar(zone, aLocale);
                    break;
                case "gregory":
                    cal = new GregorianCalendar(zone, aLocale);
                    break;
                }
            }
        }
        if (cal == null) {
            // If no known calendar type is explicitly specified,
            // perform the traditional way to create a Calendar:
            // create a BuddhistCalendar for th_TH locale,
            // a JapaneseImperialCalendar for ja_JP_JP locale, or
            // a GregorianCalendar for any other locales.
            // NOTE: The language, country and variant strings are interned.
            if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") {
                cal = new BuddhistCalendar(zone, aLocale);
            } else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja"
                       && aLocale.getCountry() == "JP") {
                cal = new JapaneseImperialCalendar(zone, aLocale);
            } else {
                cal = new GregorianCalendar(zone, aLocale);
            }
        }
        return cal;
    }
로그인 후 복사

위 내용은 Java 팩토리 패턴 예제 코드 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:yisu.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿