小工具知识网

当前位置: 首页 > 行业知识 > 【Java设计模式】三、

行业知识

【Java设计模式】三、

2026-10-21 12:53:52 来源:互联网转载

文章目录

  • 0、案例:咖啡屋
  • 1、简单工厂模式 + 静态工厂(不属于23种之列)
  • 2、工厂方法模式
  • 3、抽象工厂模式
  • 4、建造者模式
  • 5、原型��计模式

    0、案例:咖啡屋

    模拟咖啡店点餐。咖啡有多种,抽象类,子类为各种咖啡。咖啡店类聚合咖啡类。类图如下:

    定义咖啡抽象类:

    public abstract class Coffee {//获取咖啡种类名称public abstract String getName();//加奶public void addMilk() {System.out.println("加奶");}//加糖public void addSugar() {System.out.println("加糖");}}

    各种咖啡:

    public class AmericanCoffee extends Coffee{@Overridepublic String getName(){return "美式";}}
    public class LatteCoffee extends Coffee{@Overridepublic String getName(){return "拿铁";}}

    咖啡屋类,聚合咖啡抽象类:

    public class CoffeeStore {    public Coffee orderCoffee(String type) {        Coffee coffee = null;        if("americano".equals(type)) {            coffee = new AmericanoCoffee();        } else if("latte".equals(type)) {            coffee = new LatteCoffee();        } else {        throw new RuntimeException("店里没这种咖啡");        }        return coffee;    }}

    1、简单工厂模式 + 静态工厂(不属于23种之列)

    即由一个工厂决定创建哪一种产品类型的实例。 包括:

    • 抽象产品(抽象类)
    • 具体产品(子类)
    • 具体工厂(创建产品并提供方法给调用者)

      改进上面的咖啡案例,引入工厂类,让咖啡屋不再自己创建咖啡对象,而是直接从工厂获取,类图:

      /** * 咖啡工厂类 */public class SimpleCoffeeFactory {    public Coffee createCoffee(String type) {        Coffee coffee = null;        if("americano".equals(type)) {            coffee = new AmericanoCoffee();        } else if("latte".equals(type)) {            coffee = new LatteCoffee();        }        return coffee;    }}
      //新的咖啡屋类public class CoffeeStore {    public Coffee orderCoffee(String type) {        SimpleCoffeeFactory factory = new SimpleCoffeeFactory();        Coffee coffee =  factory.createCoffee(type);        //加配料        coffee.addMilk();        coffee.addsugar();        return coffee;    }}

      到这儿,有个疑惑,咖啡抽象类或子类变时,SimpleCoffeeFacroty类不还得变?这和直接咖啡屋类有啥区别?不都是改一个类?多此一举?其实不然,如果有一百家咖啡屋,而你没有工厂,那需求变更时你就得改一百次代码,而有了工厂,你只需改工厂一个类就行。本质还是这个工厂类带来了解耦。简单工厂可扩展为静态工厂(即把创建对象的方法改为静态的):

      public class SimpleCoffeeFactory {//静态的    public static Coffee createCoffee(String type) {        Coffee coffee = null;        if("americano".equals(type)) {            coffee = new AmericanoCoffee();        } else if("latte".equals(type)) {            coffee = new LatteCoffee();        }        return coffe;    }}

      但这种模式下,工厂类还是得修改,并不符合开闭原则。

      2、工厂方法模式

      • 定义一个接口或者一个抽象的工厂类,让它的实现类(也是一个工厂)来决定创建哪一个实例对象。
      • 根据每个工厂不同的方法,来产生不同的所需要的对象

        角色有:

        • 抽象工厂:只提供创建产品的接口给外界调用
        • 具体工厂:实现抽象工厂,完成具体产品的创建
        • 抽象产品:咖啡类
        • 具体产品:美式、拿铁

          继续完善案例:

          抽象工厂,只提供一个方法:

          public interface CoffeeFactory {Coffee createCoffee();   //生产咖啡对象}

          具体的工厂类,实现抽象工厂:美式咖啡工厂、拿铁咖啡工厂

          //美式咖啡工厂,专门用来生产美式咖啡public class LatteCoffeeFactory implements CoffeeFactory {    public Coffee createCoffee() {        return new LatteCoffee();    }    }//拿铁咖啡工厂,专门用来生产拿铁咖啡public class AmericanCoffeeFactory implements CoffeeFactory {    public Coffee createCoffee() {        return new AmericanCoffee();    }    }

          注意现在的咖啡店类:1)、它依赖于抽象,聚合的是抽象工厂对象 2)、创建咖啡店对象,需要set传一个咖啡工厂对象

          public class CoffeeStore {    private CoffeeFactory factory;//通过构造方法来赋值    public CoffeeStore(CoffeeFactory factory) {        this.factory = factory;    }//也可setpublic void setFactory(CoffeeFactory factory) {this.factory = factory;}    public Coffee orderCoffee(String type) {        Coffee coffee = factory.createCoffee();   //直接调抽象类的方法,到时是哪个子工厂,就能创建出哪种咖啡        //加配料        coffee.addMilk();        coffee.addsugar();        return coffee;    }}

          测试类:

          public class Client {public static void main(Stirng[] args) {//创建咖啡店对象CoffeeStore store = new CoffeeStore();//创建具体的咖啡工厂CoffeeFactory factory = new AmericanCoffeeFactory();store.setFactory(factory);//点咖啡Coffee coffee = store.orderCoffee();//获取咖啡名称System.out.println(coffee.getName());}}

          此时,再有新品种咖啡进来,只需新增代码NewCoffeeFactory去实现CoffeeFactory,以及新增Coffee的子类NewCoffee。测试类中自然就是:

          //创建具体的咖啡工厂CoffeeFactory factory = new NewCoffeeFactory();store.setFactory(factory);//....

          3、抽象工厂模式

          前面的工厂方法模式,生产的都是相同系列的对象,如Java课程、python课程。抽象工厂模式则是提供创建一系列相关或相互依赖对象的接口。比如生产汽车,将汽车分为车架、车门、底盘等各个零部件进行生产。

          public interface CarFactory{//获取车门对象public CarDoor getCarDoor();//获取车架对象public CarFrame getCarFrame();//获取底盘对象public CarBasePlate getCarBasePlate();//制作汽车public void make();}
          //车门工厂public abstract class CarDoorFactory{public abstract void make();}
          //底盘工厂public abstract class CarBasePlateFactory{public abstract void make();}
          //车架工厂public abstract class CarFrameFactory{public abstract void make();}
          //车门public class CarDoor extends CarDoorFactory{@Overridepublic abstract void make(){System.out.println("制作车门");}}
          //底盘public class CarBasePlate extends CarBasePlateFactory{public abstract void make(){System.out.println("制作车底盘");}}
          //车架工厂public class CarFrame extends CarFrameFactory{public abstract void make(){System.out.println("制作车架");}}
          public class Car implements CarFactory{private CarDoor carDoor = null;private CarFrame carFrame = null;private CarBasePlate carBasePlate = null;@Overridepublic CarDoor getCarDoor(){carDoor = new CarDoor();return carDoor;}@Overridepublic CarFrame getCarFrame(){carFrame = new new CarFrame();return carFrame;}@Overridepublic CarBasePlate getCarBasePlate(){carBasePlate = new CarBasePlate();return carBasePlate;}@Overridepublic void make(){carDoor.make();carFrame.make();carBasePlate.make();System.out.print("小汽车制作完成");}}

          测试:

          public class Test{public static void mian(STring[] args){Car car  = new Car();car.getCarBasePlate();car.getCarFrame();car.getCarDoor();car.make();}}

          运行:

          4、建造者模式

          • 将复杂的对象的创建 和 属性赋值所分离
          • 建造的过程和细节我们不需要知道,只需要通过构建者去进行操作
            @Datapublic class Car{private String basePlate;   //车底盘private String frame;//车架private String door; //车门}
            public abstract class Builder{//车底盘public abstract void buildBasePlate(String basePlate);//车架public abstract void buildCarFrame(String carFrame);//车门public abstract void buildCarDoor(String carDoor);//制作车public abstract Car makeCar();}

            写实现类:

            public class CarBuilder extends Builder{private Car car = new Car();@Overridpublic abstract void buildBasePlate(String basePlate){car.setBasePlate(basePlate);}@Overridepublic abstract void buildCarFrame(String carFrame){car.setFrame(frame);}@Overridepublic abstract void buildCarDoor(String carDoor){car.setDoor(carDoor);}@Overridepublic abstract Car makeCar(){return this.car;}}

            创建一个工程师:

            public class Engineer{private CarBuilder carBuilder;//自动注入、构造方法、set方法都行,能完成赋值就行,这里写setpublic void setCarBuilder(CarBuilder carBuilder){this.carBuilder = carBuilder;}public Car mekeCar(String basePlate, String frame, String door){carBuilder.buildBasePlate(basePlate);carBuilder.buildCarFrame(frame);carBuilder.buildCarDoor(door);return carBuilder.makeCar();}}

            测试:

            public class Test{public static void mian(STring[] args){Engineer engineer = new Engineer();CarBuilder carBuilder = new CarBuilder();engineer.setCarBuilder(carBuilder);Car car = engineer.makeCar("制作汽车底盘","制作汽车车架","制作汽车车门");System.out.println(car);}}

            运行:

            5、原型设计模式

            • 用于创建重复的对象,能够保证创建对象的性能
            • 是创建对象的最佳方式
              @Datapublic class Pig{private String name;   //名字private String doSomething;  //喜欢做的事}

              现在要表示佩奇一家,正常创建流程如下:

              public class Test{public static void mian(STring[] args){Pig peki = new Pig();peki.setName("佩琪");peki.setDoSomething("喜欢吃蛋糕");System.out.println(peki);Pig george = new Pig();george.setName("乔治");george.setDoSomething("喜欢睡觉");System.out.println(george);Pig pigDad = new Pig();pigDad.setName("猪爸爸");pigDad.setDoSomething("喜欢开车");System.out.println(pigDad);Pig pigMum = new Pig();pigMum.setName("猪妈妈");pigMum.setDoSomething("喜欢做饭");System.out.println(pigMum);}}

              运行:

              采用原型设计模式后:实体类实现Cloneable接口

              @Datapublic class Pig implements Cloneable{public Pig() {System.out.println("小猪被初始化了...");}private String name;   //名字private String doSomething;  //喜欢做的事@Overrideprotected Object clone() throws CloneNotSupportedException{return super.clone();}}

              再次创建佩奇一家:

              public class Test{public static void mian(STring[] args){Pig peki = new Pig();    //先new一个peki.setName("佩琪");peki.setDoSomething("喜欢吃蛋糕");System.out.println(peki);Pig george = (Pig) peki.clone();    //后面就克隆george.setName("乔治");    //如果这里不赋值,那克隆出来的属性和克隆样本一样george.setDoSomething("喜欢睡觉");System.out.println(george);Pig pigDad = (Pig) peki.clone() ;pigDad.setName("猪爸爸");pigDad.setDoSomething("喜欢开车");System.out.println(pigDad);Pig pigMum = (Pig) peki.clone() ;pigMum.setName("猪妈妈");pigMum.setDoSomething("喜欢做饭");System.out.println(pigMum);}}

              运行:

              发现构造方法只被调用了一次,且出来的也照样是不同的对象。因此,当对象属性很多,而又要创建大量这种对象时,就可以用原型设计模式。该模式产生的对象,虽然都是不同的对象,单如果不重新赋值,属性却是与克隆样本保持一致的,即使是一个新的对象。

上一篇:电视连接什么主机好用吗

下一篇:服务器怎么进去目录页面?