伤心客 发表于 2023-9-7 01:43:33

工厂设计模式

工厂设计模式

简单(静态)工厂模式

基本介绍


[*]1.简答工厂模式,属于创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单,最实用的模式。
[*]2.简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为。
[*]3.在软件开发中,当使用到大量的创建某类,或某些对象时,就会使用到工厂模式。
案例代码

/**
* 抽象的披萨类
* @author 长名06
* @version 1.0
*/
public abstract class Pizza {

    private String name;

    public abstract void prepare();

    public void bake(){
      System.out.println(name + "烘烤完成");
    }

    public void cut(){
      System.out.println(name + "切割完成");
    }

    public void box(){
      System.out.println(name + "打包完成");
    }

    public void setName(String name) {
      this.name = name;
    }
}

//具体披萨类
public class PepperPizza extends Pizza{
    @Override
    public void prepare() {
      System.out.println("胡椒披萨准备原材料");
    }
}

public class GreekPizza extends Pizza{
    @Override
    public void prepare() {
      System.out.println("希腊披萨准备原材料");
    }
}
public class CheesePizza extends Pizza{
    @Override
    public void prepare() {
      System.out.println( "芝士披萨" + "准备原材料");
    }
}
//简单工厂类
public class SimpleFactory {

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

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

/**
* @author 长名06
* @version 1.0
*/
public class OrderPizza {

    private BufferedReader br;

    public OrderPizza() {
      Pizza pizza = null;
      do {
            String pizzaType = this.getType();
            pizza = SimpleFactory.createPizza(pizzaType);
            if(pizza != null) {
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
            } else {
                if(br != null){
                  try {
                        br.close();
                  } catch (IOException e) {
                        e.printStackTrace();
                  }
                }
                break;
            }
      }while (true);
    }

    public String getType() {
      br = new BufferedReader(new InputStreamReader(System.in));
      System.out.println("input pizza type:");
      String type = "";
      try {
            type = br.readLine();
      }catch (IOException e){
            e.printStackTrace();
      }
      return type;
    }

}

public class PizzaStore {
    public static void main(String[] args) {
      new OrderPizza();
    }
}工厂方法模式

披萨案例新需求

客户在点披萨的时候,可以点不同地区的披萨,比如北京的奶酪披萨,北京的胡椒披萨或者时伦敦的奶酪披萨,伦敦的胡椒披萨。
思路分析,使用简答工厂模式,创建不同的简单工厂类,比如BJPizzaSimpleFactory,LDPizzaSimpleFactory等,从当前的案例,来说可以使用,但是考虑到项目的规模,及软件的可维护性,扩展性不是很好。
使用工厂方法模式
基本介绍

工厂方法模式设计方案,将披萨项目的实例化功能抽象成抽象方法,在不同的口味点餐子类中实现。
工厂方法模式:定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类实现。
UML类图

https://img2023.cnblogs.com/blog/2883613/202309/2883613-20230906233242086-1818676391.png
案例代码

public abstract class Pizza {

    private String name;

    public abstract void prepare();

    public void bake(){
      System.out.println(name + "烘烤完成");
    }

    public void cut(){
      System.out.println(name + "切割完成");
    }

    public void box(){
      System.out.println(name + "打包完成");
    }

    public void setName(String name) {
      this.name = name;
    }

}

public class LDPepperPizza extends Pizza{
    @Override
    public void prepare() {
      System.out.println("伦敦胡椒披萨准备原材料");
    }
}

public class LDCheesePizza extends Pizza{
    @Override
    public void prepare() {
      System.out.println("伦敦芝士披萨准备原材料");
    }
}

public class BJPepperPizza extends Pizza{
    @Override
    public void prepare() {
      System.out.println("北京胡椒披萨准备原材料");
    }
}

public class BJCheesePizza extends Pizza{
    @Override
    public void prepare() {
      System.out.println("北京芝士披萨准备原材料");
    }
}

public abstract class OrderPizza {
    private BufferedReader br;

    public abstract Pizza createPizza(String type);

    public OrderPizza() {
      Pizza pizza = null;
      do {
            String pizzaType = this.getType();
            pizza = createPizza(pizzaType);
            if(pizza != null) {
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
            } else {
                if(br != null){
                  try {
                        br.close();
                  } catch (IOException e) {
                        e.printStackTrace();
                  }
                }
                break;
            }
      }while (true);
    }

    public String getType() {
      br = new BufferedReader(new InputStreamReader(System.in));
      System.out.println("input pizza type:");
      String type = "";
      try {
            type = br.readLine();
      }catch (IOException e){
            e.printStackTrace();
      }
      return type;
    }
}

public class LDOrderPizza extends OrderPizza{
    @Override
    public Pizza createPizza(String type) {
      Pizza pizza = null;
      if(type.equals("cheese")){
            pizza = new BJCheesePizza();
            pizza.setName("北京伦敦披萨");
      }else if(type.equals("pepper")){
            pizza = new BJPepperPizza();
            pizza.setName("北京胡椒披萨");
      }
      return pizza;
    }
}

public class BJOrderPizza extends OrderPizza{

    @Override
    public Pizza createPizza(String type) {
      Pizza pizza = null;
      if(type.equals("cheese")){
            pizza = new BJCheesePizza();
            pizza.setName("北京伦敦披萨");
      }else if(type.equals("pepper")){
            pizza = new BJPepperPizza();
            pizza.setName("北京胡椒披萨");
      }
      return pizza;
    }
}

//测试类
public class PizzaStore {
    public static void main(String[] args) {
      new LDOrderPizza();
    }
}抽象工厂模式

基本介绍


[*]1.抽象工厂模式,定义了一个interface用于创建相关或有依赖关系的对象簇,而无需指明具体的类。
[*]2.抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合。
[*]3.从设计层面看,抽象工厂模式就是对简单工厂模式的改进(也叫进一步抽象)。
[*]4.将工厂抽象为两层,AbsFactory(抽象工厂)和具体实现的工厂子类。程序员可以根据创建对象类型使用对象的工厂子类。这样将单个的简单工厂变成了工厂簇,更利于代码的维护和扩展。
uml类图

https://img2023.cnblogs.com/blog/2883613/202309/2883613-20230906234025166-1677054319.png
案例代码

Pizza类,及其子类,同上工厂方法模式
public interface AbsFactory {
    //让子类工厂实现
    public Pizza createPizza(String type);
}
//北京工厂
public class BJFactory implements AbsFactory{
    @Override
    public Pizza createPizza(String type) {
      System.out.println("使用的是抽象工厂模式~");
      Pizza pizza = null;
      if(type.equals("cheese")){
            pizza = new BJCheesePizza();
            pizza.setName("北京芝士披萨");
      }else if(type.equals("pepper")){
            pizza = new BJPepperPizza();
            pizza.setName("北京胡椒披萨");
      }
      return pizza;
    }
}
//伦敦工厂
public class LDFactory implements AbsFactory{
    @Override
    public Pizza createPizza(String type) {
      System.out.println("使用的是抽象工厂模式~");
      Pizza pizza = null;
      if(type.equals("cheese")){
            pizza = new LDCheesePizza();
            pizza.setName("伦敦芝士披萨");
      }else if(type.equals("pepper")){
            pizza = new LDPepperPizza();
            pizza.setName("伦敦胡椒披萨");
      }
      return pizza;
    }
}
//披萨订单
public class OrderPizza {

    private BufferedReader br;

    private AbsFactory absFactory;

    public OrderPizza(AbsFactory absFactory){
      setAbsFactory(absFactory);
    }

    private void setAbsFactory(AbsFactory absFactory) {
      Pizza pizza = null;
      String pizzaType = "";
      this.absFactory = absFactory;
      do{
            pizzaType = this.getType();
            pizza = this.absFactory.createPizza(pizzaType);
            if(pizza == null){
                try {
                  System.out.println("订购失败");
                  br.close();
                } catch (IOException e) {
                  e.printStackTrace();
                }
                break;
            }else{
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
            }
      }while (true);
    }


    public String getType() {
      br = new BufferedReader(new InputStreamReader(System.in));
      System.out.println("input pizza type:");
      String type = "";
      try {
            type = br.readLine();
      }catch (IOException e){
            e.printStackTrace();
      }
      return type;
    }
}
//测试代码
public class PizzaStore {
    public static void main(String[] args) {
//      new OrderPizza(new BJFactory());
      new OrderPizza(new LDFactory());
    }
}工厂模式在JDK-Calendar中的应用

https://img2023.cnblogs.com/blog/2883613/202309/2883613-20230906234416864-574953154.png
核心代码

if (aLocale.hasExtensions()) {//判断当前时区是否有扩展
    String caltype = aLocale.getUnicodeLocaleType("ca");
    if (caltype != null) {
      switch (caltype) {//采用switch分支创建实例
      case "buddhist":
      cal = new BuddhistCalendar(zone, aLocale);
            break;
      case "japanese":
            cal = new JapaneseImperialCalendar(zone, aLocale);
            break;
      case "gregory":
            cal = new GregorianCalendar(zone, aLocale);
            break;
      }
    }
}工厂模式小结


[*]1.工厂模式的作用,将创建对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目解耦的目的。从而提高项目的扩展和维护性。
[*]2.三种工厂模式(简单工厂模式,工厂方法模式,抽象工厂模式)。
[*]3.创建对象实例时,不是直接new对象,而是将new对象的动作,放在一个工厂的方法里,并返回创建的对象。
[*]4.设计模式的依赖倒转原则和里氏替换原则,不要让类继承具体的类,而是继承抽象类和interface,不要覆盖基类中已实现的方法。
案例只是为了体现这种设计模式的思想,不具有实际意义
只是为了记录自己的学习历程,且本人水平有限,不对之处,请指正。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 工厂设计模式