您的位置:首页 > 房产 > 建筑 > 工厂模式-小记

工厂模式-小记

2025/1/10 6:04:12 来源:https://blog.csdn.net/m0_63622279/article/details/141967135  浏览:    关键词:工厂模式-小记

工厂模式-小记

    • 工厂模式
    • 简单工厂模式
      • 场景复现
      • 抽象产品接口
      • 具体产品
      • 工厂类
      • 测试方法
    • 工厂方法模式
      • 工厂方法模式
      • 场景描述
      • 抽象工厂接口
      • 具体工厂
      • 抽象产品
      • 具体产品
      • 客户端测试
    • 抽象工厂模式
      • 场景描述
      • 抽象工厂
      • 具体工厂
      • 抽象产品
      • 具体产品
      • 客户端测试
    • 三者的对比

工厂模式

工厂模式提供了一种创建对象的最佳方式,在工厂模式中,我们创建对象时不会对客户端暴露创建逻辑,而是通过使用一个共同的接口来指向新创建的对象。

  • 简单工厂模式
  • 工厂方法模式
  • 抽象工厂模式

优点:

  • 解耦:将对象的创建与使用分离,使得系统更加灵活。
  • 易于扩展:当需要增加新的咖啡类型时,只需增加新的实现类,并在工厂类中添加相应的逻辑即可,无需修改客户端代码。

缺点:

  • 增加复杂度:当系统中存在大量的产品类时,工厂类的逻辑可能会变得非常复杂。
  • 违反开闭原则:在简单工厂模式中,增加新的产品类时,通常需要修改工厂类,这违反了开闭原则(对扩展开放,对修改关闭)。

简单工厂模式

简化客户端代码,通过一个工厂类来创建对象。

场景复现

假设我们有一个咖啡店,它提供多种咖啡的制作。每种咖啡(如拿铁、卡布奇诺、美式等)的制作过程略有不同,但我们希望有一个统一的接口来订购咖啡,而不需要知道每种咖啡的具体制作过程。

抽象产品接口

咖啡接口:定义制作咖啡的方法

public interface Coffee{void prepareRecipe();
}

具体产品

实现咖啡接口的具体咖啡类(如Espresso、Latte、Cappuccino等)

public class Espresso implements Coffee{@Overridepublic void prepareRecipe(){System.out.println("Preparing Espresso");}
}public class Latte implements Coffee {@Overridepublic void prepareRecipe() {System.out.println("Preparing Latte");}
}

工厂类

咖啡工厂类:这个类根据传入的类型信息返回相应的咖啡对象

public class CoffeeFactory {public static Coffee getCoffee(String type){if(type == null){return null;}if(type.equalsIgnoreCase("espresso")){return new Espresso();}else if(type.equalsIgnoreCase("latte")){return new Latte();}return null;}
}

测试方法

订购咖啡测试方法:

public static void main(String[] args) {Coffee myCoffee = CoffeeFactory.getCoffee("latte");if (myCoffee != null) {myCoffee.prepareRecipe();}
}

工厂方法模式

工厂方法模式

工厂方法模式与简单工厂模式相比,工厂方法模式提供了更高的灵活性和更好的扩展性。

定义:工厂方法模式定义了一个创建对象的接口,但允许子类决定实例化哪一个类。工厂方法让类的实例化推迟到子类。

目的

  • 解耦:将对象的创建与使用对象的代码解耦。
  • 扩展性:当需要添加新的产品时,只需要增加新的具体工厂类,而不需要修改已有的工厂接口或客户端代码。
  • 遵循开闭原则:对扩展开放,对修改关闭。

结构

  • 抽象工厂:定义一个用于创建产品的接口。
  • 具体工厂:实现抽象工厂中的接口,完成具体产品的创建。
  • 抽象产品:定义产品的规范,描述所有实例所共有的公共接口。
  • 具体产品:由具体工厂创建的对象。

优点

  • 易于扩展:当需要添加新的图形类型时,只需要增加一个新的具体工厂类即可,不需要修改已有的工厂接口或客户端代码。
  • 解耦:客户端只依赖于抽象工厂接口,而不依赖于具体的工厂实现。
  • 遵循开闭原则:对扩展开放,对修改关闭。

缺点

  • 增加复杂性:对于每一种产品都需要一个具体的工厂类,增加了系统的复杂性。
  • 多态性限制:如果需要创建的产品具有不同的接口,则不适合使用工厂方法模式。

应用场景

  • 当系统中存在多个产品等级结构时:例如,不同的图形类。
  • 当希望客户端独立于如何创建对象以及对象的实际实现时:例如,客户端只需要知道如何获取图形对象,而不关心具体的创建逻辑。
  • 当一个类希望由它的子类来指定它所创建的对象时:例如,父类定义一个工厂方法,由子类实现具体的创建逻辑。

总结:工厂方法模式通过定义一个创建对象的接口,并让具体的子类决定实例化哪一个类,从而将对象的创建与使用对象的代码解耦。这种方式不仅提高了代码的可扩展性,而且遵循了开闭原则,使得系统更加灵活和易于维护

场景描述

创建一个图形绘制系统,支持圆形,原形,矩形和三角形。每种图形应该包含基础的绘图方法

抽象工厂接口

public interface ShapeFactory {Shape getShape();
}

具体工厂

为上述图形(圆形,原形,矩形和三角形)提供具体的工厂类

public class CircleFactory implements ShapeFactory {@Overridepublic Shape getShape() {return new Circle();}
}public class RectangleFactory implements ShapeFactory {@Overridepublic Shape getShape() {return new Rectangle();}
}public class TriangleFactory implements ShapeFactory {@Overridepublic Shape getShape() {return new Triangle();}
}

抽象产品

public interface Shape {void draw();
}

具体产品

public class Circle implements Shape {@Overridepublic void draw() {System.out.println("Drawing a circle.");}
}public class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Drawing a rectangle.");}
}public class Triangle implements Shape {@Overridepublic void draw() {System.out.println("Drawing a triangle.");}
}

客户端测试

public class Client {public static void main(String[] args) {ShapeFactory circleFactory = new CircleFactory();Shape circle = circleFactory.getShape();circle.draw();ShapeFactory rectangleFactory = new RectangleFactory();Shape rectangle = rectangleFactory.getShape();rectangle.draw();ShapeFactory triangleFactory = new TriangleFactory();Shape triangle = triangleFactory.getShape();triangle.draw();}
}

抽象工厂模式

抽象工厂模式,提供了一种创建一系列相关或依赖对象的接口,而无需指定它们具体的类。

创建一组相关的产品对象,确保它们协同工作 (如:电脑需要有外设:键盘+鼠标+音响 才能更好的协同工作)

结构:

  • 抽象工厂:定义一个用于创建产品的几口。
  • 具体工厂:实现抽象工厂中的接口,完成具体产品的创建。
  • 抽象产品:定义产品的规范,描述所有实例共有的公共接口。
  • 具体产品:由工厂创建的对象。

优点:

  • 封装性:抽象工厂模式将产品族的创建封装在一个工厂类中,使得客户端不需要关心具体的创建逻辑。
  • 易扩展:如果需要添加新的产品族(如 Linux 风格),只需添加一个新的具体工厂类即可。
  • 一致性:保证同一产品族中的产品对象协同工作,避免了不同风格的产品混用带来的问题。

缺点:

  1. 增加复杂性:抽象工厂模式增加了系统的复杂性,因为需要定义更多的接口和类。
  2. 难以修改产品族:如果需要修改某个产品族中的产品,可能需要修改多个类。
  3. 违反开闭原则:如果需要添加新的产品类型(如新的控件),需要修改现有的工厂类。

应用场景

  • 需要创建一系列相关产品:例如,创建不同风格的界面组件。
  • 产品族中的产品需要协同工作:例如,不同风格的按钮和文本框需要一致的外观和行为。

总结:抽象工厂模式通过定义一个创建一系列相关或依赖对象的接口,使得客户端可以方便地创建一组相关的产品对象。这种方式使得系统更加模块化、易于扩展和维护。在实际应用中,抽象工厂模式特别适用于需要创建多个相关产品族的场景。

场景描述

如:QQ登录窗体,由文本输入框和按钮组合完成登录功能。对于mac,linux,win,移动端,qq的登录窗体可能展现风格是不同的或者相同的,但是基本都是由 按钮和输入框完成。此时就可以使用抽象工厂来完成。

抽象工厂

public interface GUIFactory {Button createButton();TextField createTextField();
}

具体工厂

// WindowsFactory
public class WindowsFactory implements GUIFactory {@Overridepublic Button createButton() {return new WindowsButton();}@Overridepublic TextField createTextField() {return new WindowsTextField();}
}// MacFactory
public class MacFactory implements GUIFactory {@Overridepublic Button createButton() {return new MacButton();}@Overridepublic TextField createTextField() {return new MacTextField();}
}

抽象产品

public interface Button {void paint();
}public interface TextField {void paint();
}

具体产品

public class WindowsButton implements Button {@Overridepublic void paint() {System.out.println("Painting a Windows button.");}
}public class MacButton implements Button {@Overridepublic void paint() {System.out.println("Painting a Mac button.");}
}public class WindowsTextField implements TextField {@Overridepublic void paint() {System.out.println("Painting a Windows text field.");}
}public class MacTextField implements TextField {@Overridepublic void paint() {System.out.println("Painting a Mac text field.");}
}

客户端测试

public class Client {public static void main(String[] args) {// 使用 Windows 风格的工厂GUIFactory windowsFactory = new WindowsFactory();Button windowsButton = windowsFactory.createButton();TextField windowsTextField = windowsFactory.createTextField();windowsButton.paint();windowsTextField.paint();// 使用 Mac 风格的工厂GUIFactory macFactory = new MacFactory();Button macButton = macFactory.createButton();TextField macTextField = macFactory.createTextField();macButton.paint();macTextField.paint();}
}

三者的对比

简单工厂 vs 工厂方法 vs 抽象工厂:

  1. 扩展性
    简单工厂模式:扩展性较差,因为需要修改工厂类来添加新的产品类型。
    工厂方法模式:扩展性较好,通过新增具体工厂类来添加新产品类型。
    抽象工厂模式:扩展性好,通过新增具体工厂类来添加新产品族,但修改产品族较难。
  2. 解耦
    简单工厂模式:客户端依赖于具体的工厂类。
    工厂方法模式:客户端依赖于抽象工厂接口。
    抽象工厂模式:客户端依赖于抽象工厂接口。
  3. 支持继承
    简单工厂模式:不支持继承。
    工厂方法模式:支持继承。
    抽象工厂模式:支持继承。
  4. 创建对象的类型
    简单工厂模式:创建单个对象。
    工厂方法模式:创建单个对象。
    抽象工厂模式:创建一系列相关对象。
  5. 适用场景
    简单工厂模式:适用于创建的对象较少,且不经常需要添加新类型的情况。
    工厂方法模式:适用于需要创建多个相关产品,并且未来可能需要添加新产品类型的情况。
    抽象工厂模式:适用于需要创建多个相关产品族,并且未来可能需要添加新产品族的情况。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com