Skip to content

2019-06-28:谈一谈单例模式,建造者模式,工厂模式的使用场景?如何合理选择? #86

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
MoJieBlog opened this issue Jun 28, 2019 · 5 comments

Comments

@MoJieBlog
Copy link
Collaborator

No description provided.

@yangfanggang
Copy link

抛砖引玉

单例模式 顾名思义,只有一个实例,一般用来网络请求的实例

建造者模式,不是很熟悉,AlertDialog的创建使用的是这个

工厂模式,批量生产相似的产品,可用来设计Activity的基类

@Moosphan Moosphan changed the title 2019-06-28:谈一谈单例模式,建造者模式,工厂模式的使用场景?如何合理选择? 2019-06-28:谈一谈单例模式,建造者模式,工厂模式的使用场景?如何合理选择? Jul 1, 2019
@Vicent9920
Copy link

  • 单例模式,一般是指将消耗内存、属性和对象支持全局公用的对象,应该设置为单例模式,如持久化处理(网络、文件等)
  • 建造者模式,一般见于开发的框架或者属性时可以直接链式设置属性,比如我们看到的AlertDialog,一般用在某些辅助类(如BRVAHBaseViewHolder)或者开发的框架的时候方便连续设置多个属性和调用多个方法。
  • 工厂模式,一般用于业务的实体创建,在创建的过程中考虑到后期的扩展。在Android源码中比较常见的有BitmapFactory`LayoutInflater.Factory,在实体编码的过程中,比如BRVAH的多布局,如果数据类型比较多或者后期需要扩展,则可以通过工厂布局的方式,将实现MultiItemEntity `接口的实体通过工厂模式创建:
object MultiItemEntityFactory{
    val TEXT = 1
    val IMG = 2
    val TEXT_IMG = 3

    fun createBean(type:Int): MultiItemEntity {
        when(type){
            TEXT -> return BeanA()
            IMG -> return BeanB()
            TEXT_IMG -> return BeanC()
            else -> return BeanA()
        }
    }
}
class MultipleItemQuickAdapter(data: List<*>) : BaseMultiItemQuickAdapter<MultiItemEntity, BaseViewHolder>(data) {

    init {
        addItemType(MultipleItem.TEXT, R.layout.text_view)
        addItemType(MultipleItem.IMG, R.layout.image_view)
    }

    override fun convert(helper: BaseViewHolder, item: MultipleItem) {
        ...
    }

}

@18361237136
Copy link

  1. 单例模式:保证全局只有一个实例,如网络请求
  2. 建造者模式:用于需要设置比较多的属性可以用直接链式,如AlerDialog
  3. 工厂模式:用于业务的实体类创建,易于扩展,如BitMapFactory

@AndroidJiang
Copy link

简单工厂:一工厂 多产品;
工厂方法:多工厂 多产品;

@Jaktion
Copy link

Jaktion commented Jan 15, 2025

单例模式
使用场景
资源共享场景:例如数据库连接池,在应用程序中通常只需要一个数据库连接池实例来管理和分配数据库连接。因为数据库连接的创建和销毁是比较耗费资源的操作,通过单例模式确保只有一个连接池实例,可以有效地控制资源的使用,避免频繁地创建和销毁连接,提高系统性能。
全局配置管理场景:像系统的配置文件读取和管理,一般只需要一个实例来加载和维护配置信息。例如,一个应用程序的配置类,它读取配置文件中的参数(如服务器地址、端口号等),并提供访问这些参数的方法。通过单例模式可以保证在整个应用程序运行期间,配置信息的一致性和唯一性。
日志记录器场景:在一个应用程序中,通常只需要一个日志记录器来记录系统运行过程中的各种信息。这样可以方便地将所有的日志信息集中管理,并且能够按照统一的格式和规则进行记录。例如,一个简单的日志记录器单例可以将日志信息输出到文件或者控制台。
实现方式示例(Java 中的懒汉式单例)
java
class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
原理:单例模式的核心是确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。在上述示例中,私有构造函数防止外部类直接创建实例,getInstance方法用于获取单例对象。通过静态变量instance来保存唯一的实例,并且使用synchronized关键字保证在多线程环境下的正确性。
建造者模式
使用场景
复杂对象创建场景:当需要创建的对象具有复杂的内部结构,并且对象的属性设置步骤较多时,建造者模式非常有用。例如,在构建一个电脑对象时,电脑包含 CPU、内存、硬盘、显卡等多个部件,并且每个部件可能有多种选择和不同的配置参数。使用建造者模式,可以将电脑的构建过程封装在一个建造者类中,通过链式调用等方式逐步设置各个部件的参数,最后构建出完整的电脑对象。
对象属性有多种组合方式场景:对于一些对象,其属性组合方式多种多样,不同的组合方式可能产生不同类型的对象。例如,在创建一个房屋建筑对象时,房屋可以有不同的户型(一室一厅、两室一厅等)、不同的装修风格(欧式、中式等)。通过建造者模式,可以根据用户的需求灵活地构建出不同类型的房屋对象。
实现方式示例(简单的电脑建造者)
java
class Computer {
private String cpu;
private String memory;
private String hardDisk;
private String graphicsCard;
public void setCpu(String cpu) {
this.cpu = cpu;
}
public void setMemory(String memory) {
this.memory = memory;
}
public void setHardDisk(String hardDisk) {
this.hardDisk = hardDisk;
}
public void setGraphicsCard(String graphicsCard) {
this.graphicsCard = graphicsCard;
}
@OverRide
public String toString() {
return "Computer{" +
"cpu='" + cpu + ''' +
", memory='" + memory + ''' +
", hardDisk='" + hardDisk + ''' +
", graphicsCard='" + graphicsCard + ''' +
'}';
}
}
class ComputerBuilder {
private Computer computer = new Computer();
public ComputerBuilder setCpu(String cpu) {
computer.setCpu(cpu);
return this;
}
public ComputerBuilder setMemory(String memory) {
computer.setMemory(memory);
return this;
}
public ComputerBuilder setHardDisk(String hardDisk) {
computer.setHardDisk(hardDisk);
return this;
}
public ComputerBuilder setGraphicsCard(String graphicsCard) {
computer.setGraphicsCard(graphicsCard);
return this;
}
public Computer build() {
return computer;
}
}
原理:建造者模式将一个复杂对象的构建和它的表示分离,使得同样的构建过程可以创建不同的表示。在示例中,Computer是要构建的复杂对象,ComputerBuilder是建造者类,通过在建造者类中设置对象的各个属性,最后通过build方法返回构建好的Computer对象。
工厂模式
使用场景
对象创建逻辑复杂场景:当对象的创建过程涉及复杂的逻辑,如读取配置文件、根据不同的条件初始化对象等情况时,工厂模式可以将这些复杂的创建逻辑封装在工厂类中。例如,在一个图形绘制软件中,根据用户选择的图形类型(圆形、方形、三角形等)创建相应的图形对象,并且每个图形对象的创建可能需要进行一些特定的初始化操作(如设置颜色、大小等),工厂模式可以很好地处理这种情况。
根据不同条件创建对象场景:如果需要根据不同的运行条件(如不同的操作系统、不同的用户权限等)创建不同类型的对象,工厂模式是一个很好的选择。例如,在一个跨平台的软件中,根据操作系统是 Windows 还是 Linux,创建不同的文件系统对象来处理文件操作。
实现方式示例(简单的图形工厂)
java
interface Shape {
void draw();
}
class Circle implements Shape {
@OverRide
public void draw() {
System.out.println("Drawing a circle");
}
}
class Square implements Shape {
@OverRide
public void draw() {
System.out.println("Drawing a square");
}
}
class ShapeFactory {
public Shape createShape(String shapeType) {
if ("circle".equals(shapeType)) {
return new Circle();
} else if ("square".equals(shapeType)) {
return new Square();
}
return null;
}
}
原理:工厂模式定义了一个用于创建对象的接口,让子类决定实例化哪一个类。在示例中,ShapeFactory是工厂类,Shape是产品接口,Circle和Square是具体的产品类。工厂类根据传入的参数决定创建哪种具体的产品对象。
合理选择
如果重点是控制对象的数量,保证一个类只有一个实例:则选择单例模式。例如,在整个系统中只需要一个全局的资源管理器或者配置管理器时,单例模式可以确保资源的唯一性和一致性。
如果需要创建复杂对象,且创建过程步骤较多、属性组合多样:建造者模式是较好的选择。它能够将复杂的对象构建过程封装起来,使得代码更易于维护和扩展,并且可以根据不同的需求灵活地构建对象。
如果对象的创建逻辑复杂,或者需要根据不同条件创建不同对象:工厂模式更合适。它将对象创建逻辑从使用对象的地方分离出来,提高了代码的可维护性和可扩展性,使得在需要修改对象创建逻辑时,只需要在工厂类中进行修改,而不影响其他部分的代码。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants