三大工厂模式(简单工厂、工厂方法、抽象工厂)

本文介绍了设计模式中的三种工厂模式:简单工厂模式、工厂方法模式和抽象工厂模式。简单工厂模式通过静态工厂方法创建对象,适用于对象创建和使用分离的场景。工厂方法模式采用工厂类接口,让具体工厂类负责创建具体产品,增强了灵活性。抽象工厂模式则用于创建一系列相关产品,适应多产品族的需求。文章通过实例代码详细阐述了每种模式的优缺点及适用场景。
摘要由CSDN通过智能技术生成

目录

设计模式的分类

1、简单工厂模式

 案例代码实现

 简单工厂优点:

 简单工厂缺点: 

2、工厂方法 

 案例代码

工厂方法模式优点:

工厂方法模式缺点:

3、抽象工厂模式

案例代码

 抽象工厂模式优点:

抽象工厂模式缺点:

适用场景:


设计模式的分类

根据目的(模式是用来做什么的)可分为创建型(Creational),结构型(Structural)和行为型(Behavioral)三类:  

  1. 创建型模式主要用于创建对象  
  2. 结构型模式主要用于处理类或对象的组合  
  3. 行为型模式主要用于描述类或对象如何交互和怎样分配职责

 创建型模式

  1. 抽象工厂模式(Abstract Factory) 
  2. 建造者模式(Builder)
  3. 工厂方法模式(Factory Method) 
  4. 原型模式(Prototype) 
  5. 单例模式(Singleton) 

结构型模式

  1. 适配器模式(Adapter)
  2. 桥接模式(Bridge)
  3. 组合模式(Composite)
  4. 装饰模式(Decorator)
  5. 外观模式(Facade)
  6. 享元模式(Flyweight)
  7. 代理模式(Proxy)

行为型模式

  1. 职责链模式(Chain of Responsibility)
  2. 命令模式(Command)
  3. 解释器模式(Interpreter)
  4. 迭代器模式(Iterator)
  5. 中介者模式(Mediator)
  6. 备忘录模式(Memento)
  7. 观察者模式(Observer)
  8. 状态模式(State)
  9. 策略模式(Strategy)
  10. 模板方法模式(Template Method)
  11. 访问者模式(Visitor) 

下面开始介绍常用的设计模式,讲解三大工厂

1、简单工厂模式

该模式虽然不属于23种设计模式,但是为了后面的引入,这个需要说说

简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式 ;在简单工厂模式中,可以根据参数的不同返回不同类的实例 ;简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类

案例:使用简单工厂模式设计一个可以创建不同几何形状的绘图工具,每个几何图形都要有绘制draw()和擦除erase()两个方法,要求在绘制不支持的几何图形时,提示一个UnSupportedShapeExceptionmoqqwrr

 案例代码实现

//抽象产品Shape
 interface  Shape {
	public  void draw();
	public  void erase();

}
//具体产品Circle
  class Circle implements Shape {

		@Override
		public void draw() {
			System.out.println("圆形在绘制");
			
		}

		@Override
		public void erase() {
			System.out.println("圆形在擦除");
		}
	}


//具体产品Rectangle 

   class Rectangle implements Shape{

		@Override
		public void draw() {
			System.out.println("现在是方形在绘制");
			
		}

		@Override
		public void erase() {
			System.out.println("现在是方形在擦除");
		}
		

	}
//具体产品Triangle
    class Triggle implements Shape{

		@Override
		public void draw() {
			System.out.println("三角形在绘制");
			
		}

		@Override
		public void erase() {
			System.out.println("三角形在擦除");
		}
		

	}


//工厂
      class ShapeFactory {
    	public static Shape createShape(String des) throws UnSupportedShapeException {
    		if(des.equals("t")) {
    			return new Triggle();
    		}
    		else if(des.equals("c")) {
    			return new Circle();
    		}
    		else if(des.equals("r")) {
    			return new Rectangle();
    			
    		}
    		else {
    			throw new UnSupportedShapeException("该几何图形不支持");
    		}
    		
    	}
    }

//自定义异常类
      class UnSupportedShapeException extends Exception {
    		public UnSupportedShapeException(String message) {
    			super(message);
    		}
    	}

//客户端测试类
public class lab1_1
{
	public static void main(String args[])
	{
         try
         {
         	Shape shape;
         	shape=ShapeFactory.createShape("a");
         	shape=ShapeFactory.createShape("t");
//         	shape=ShapeFactory.createShape("r");
//         	shape=ShapeFactory.createShape("c");
         	shape.draw();
         	shape.erase();
         }
         catch(UnSupportedShapeException e)
         {
         	System.out.println(e.getMessage());
         }
	}
}

 简单工厂优点:

  1. 实现了对象创建和使用的分离
  2. 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可
  3. 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性

 简单工厂缺点: 

  1. 工厂类集中了所有产品的创建逻辑,职责过重,一旦不能正常工作,整个系统都要受到影响,违反单一职责原则
  2. 增加系统中类的个数(引入了新的工厂类),增加了系统的复杂度和理解难度
  3. 系统扩展困难,一旦添加新产品不得不修改工厂逻辑,违反开闭原则
  4. 由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构,工厂类不能得到很好地扩展

2、工厂方法 

模式定义:在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。

 案例:某系统日志记录器要求支持多种日志记录方式,如文件记录、数据库记录等,且用户可以根据要求动态选择日志记录方式

 案例代码

//日志记录器接口:抽象产品Log
abstract class Log{
	public abstract void writeLog();
}

//文件日志记录器:具体产品FileLog
class FileLog extends Log{

	@Override
	public void writeLog() {
		System.out.println("使用文件记录日志");
		
	}
	
}

//数据库日志记录器:具体产品DatabaseLog
class DatabaseLog extends Log{

	@Override
	public void writeLog() {
		System.out.println("使用数据库记录日志");
		
	}
	
}

//日志记录器工厂接口:抽象工厂LogFactory
abstract class LogFactory{
	public abstract Log createLog();
}

//文件日志记录器工厂类:具体工厂FileLogFactory
class FileLogFactory extends LogFactory{

	@Override
	public Log createLog() {
		System.out.println("使用文件工厂");
		return new FileLog();
	}
	
}

//数据库日志记录器工厂类:具体工厂DatabaseLogFactory
class DatabaseLogFactory extends LogFactory{

	@Override
	public Log createLog() {
		System.out.println("使用数据库工厂");
		return new DatabaseLog();
	}
	
}

//客户端测试类
public class lab1_2
{
	public static void main(String args[])
	{
		LogFactory factory;
		Log log;
		factory = new FileLogFactory();
		log = factory.createLog();
		log.writeLog();
		
		factory=new DatabaseLogFactory();
		log=factory.createLog();
		log.writeLog();
	}
}

工厂方法模式优点:

  1. 工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节
  2. 能够让工厂自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部
  3. 在系统中加入新产品时,完全符合开闭原则 

工厂方法模式缺点:

  1. 系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,会给系统带来一些额外的开销
  2. 增加了系统的抽象性和理解难度

3、抽象工厂模式

模式定义:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。

在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品

 

案例:某系统为了改进数据库操作的性能,自定义数据库连接对象Connection和语句对象Statement,可针对不同类型的数据库提供不同的连接对象和语句对象,如提供Oracle或SQL Server专用连接类和语句类,而且用户可以通过配置文件等方式根据实际需要动态更换系统数据库。

案例代码

//数据库连接接口:抽象产品Connection
interface Connection{
	public void connect();
}

//Oracle数据库连接类:具体产品OracleConnection
class OracleConnection implements Connection{

	@Override
	public void connect() {
		System.out.println("Oracle数据库正在连接");
	}
	
}

//MySQL数据库连接类:具体产品MySQLConnection
class MySQLConnection implements Connection{

	@Override
	public void connect() {
		System.out.println("MySQL数据库正在连接");
		
	}
	
}

//数据库语句接口:抽象产品Statement
interface Statement{
	public void state();
}

//Oracle数据库语句类:具体产品OracleStatement
class OracleStatement implements Statement{

	@Override
	public void state() {
		System.out.println("Oracle正在使用state语句");
	}
	
}

//MySQL数据库语句类:具体产品MySQLStatement 
class MySQLStatement implements Statement{

	@Override
	public void state() {
		System.out.println("MySQL正在使用state语句");
	}
	
}

//数据库工厂接口:抽象工厂DBFactory
interface DBFactory{
	public Connection createConnection();
	public Statement createStatement();
}

//Oracle数据库工厂:具体工厂OracleFactory
class OracleFactory implements DBFactory{

	@Override
	public Connection createConnection() {
		return new OracleConnection();
	}

	@Override
	public Statement createStatement() {
		return new OracleStatement();
	}
	
}

//MySQL数据库工厂:具体工厂MySQLFactory 
class MySQLFactory implements DBFactory{

	@Override
	public Connection createConnection() {
		return new MySQLConnection();
	}

	@Override
	public Statement createStatement() {
		return new MySQLStatement();
	}
	
}

//客户端测试类
public class lab1_3{
	public static void main(String[] args) {
		try {
			DBFactory factory;
			Connection connection;
			Statement statement;
			
			factory = new MySQLFactory();
			connection =factory.createConnection();
			connection.connect();
			
			statement=factory.createStatement();
			statement.state();
			
		}catch(Exception e){
			System.out.println(e.getMessage());
		}
	}
}

 抽象工厂模式优点:

  1. 隔离了具体类的生成,使得客户端并不需要知道什么被创建
  2. 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象
  3. 增加新的产品族很方便,无须修改已有系统,符合开闭原则

抽象工厂模式缺点:

  1. 增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了开闭原则

适用场景:

  1. 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节
  2. 系统中有多于一个的产品族,但每次只使用其中某一产品族
  3. 属于同一个产品族的产品将在一起使用
  4. 产品等级结构稳定,在设计完成之后不会向系统中增加新的产品等级结构或者删除已有的产品等级结构

简单工厂模式是一种常见的创建型设计模式,它通过一个工厂类来创建不同类型的对象。在简单工厂模式中,客户端无需关心具体的对象创建过程,只需通过工厂类的静态方法来获取所需的对象实例。这样可以降低代码的耦合度,也方便了对象的创建和管理。 工厂方法模式是一种将对象的创建延迟到子类的设计模式。在工厂方法模式中,将对象的创建放在具体的工厂子类中,每个具体工厂子类负责创建一种类型的对象。客户端只需要和抽象工厂接口进行交互,具体的对象创建过程由具体子类来完成。这样可以提供一种扩展性更好的解决方案,对于新增产品类的扩展,只需要新增相应的具体工厂子类即可。 抽象工厂模式是一种提供一种创建一系列相关或依赖对象的接口,而无需指定具体类的设计模式。在抽象工厂模式中,通过定义抽象工厂接口和具体工厂类来创建一系列相关或依赖的对象。每个具体工厂类负责创建一组具体的对象,通过抽象工厂接口对外提供创建对象的方法。这样可以将具体对象的创建逻辑从客户端代码中分离出来,提高了系统的灵活性和可扩展性。 在Java中,你可以通过定义一个包含多个静态方法工厂类来实现简单工厂模式。每个静态方法对应一个具体的产品对象的创建逻辑。工厂方法模式可以通过定义一个抽象工厂接口和多个具体工厂类来实现。每个具体工厂类负责创建一种产品对象。抽象工厂模式可以通过定义一个抽象工厂接口和多个具体工厂类来实现。每个具体工厂类负责创建一组相关的产品对象。客户端通过访问抽象工厂接口来创建对象,具体的对象创建过程由具体工厂类来完成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值