设计模式(四):工厂模式(简单工厂模式、工厂方法模式、抽象工厂模式)

本文深入解析工厂模式,包括简单工厂模式、工厂方法模式和抽象工厂模式。通过实例代码展示了每种模式的应用场景,以及如何通过工厂模式实现代码解耦。

工厂模式的目的:解耦,无需客户端看到具体的类,都有工厂来进行实例化,并以基类的形式返回。

现在,大家广泛地将工厂模式分为简单工厂模式、工厂方法模式和抽象工厂模式三种。四人帮写的那本设计模式的分类为其中两种:工厂方法(factory method)模式和抽象工厂(abstract factory)模式。

这里将三种模式都进行总结。我在学习的时候,对于基类到底是采用接口类还是抽象类产生了疑问,如果你也一样,请寻找其它资料进行学习,此处依据个人理解,目前都采用抽象类,而非接口类。因为我认为Circle和Rectangle就是一种Shape,而Red和Yellow就是一种Color,而非实现某种功能的关系。

  1. 简单工厂模式:由一个工厂对象决定创建出哪一种具体产品类的实例。简单工厂模式是工厂模式中最简单实用的模式。
    在这里插入图片描述
    示例:由ShapeFactory创建Circle和Rectangle这两种Shape。

    public class SimpleFactoryDemo
    {
    	static abstract class Shape
    	{
        	void draw() {
            	System.out.println("I am a default shape");
        	}
    	}
    	
    	static class Circle extends Shape
    	{
        	@Override
        	void draw()
        	{
            	System.out.println("I am a circle.");
        	}
    	}
    
    	static class Rectangle extends Shape
    	{
        	@Override
        	void draw()
        	{
            	System.out.println("I am a rectangle.");
        	}
    	}
    	
    	static class ShapeFactory
    	{
        	public static Shape getShape(String shapeType)
        	{
            	if (shapeType.equalsIgnoreCase("circle"))
            	{
                	return new Circle();
            	}
            	else if (shapeType.equalsIgnoreCase("rectangle"))
            	{
                	return new Rectangle();
            	}
            	return null;
        	}
    	}
    
    	public static void main(String[] args)
    	{
        	String shapeType = "circle";
        	Shape shape= ShapeFactory.getShape(shapeType);
        	shape.draw();
    	}
    }
    

    这种方法思路简单,实现简单。但是如果要添加一种形状,不仅需要添加新的形状类,也要对ShapeFactory中的 if 判断语句进行修改。当然这里可以采用java的反射机制进行优化,将shapeType定义为具体形状类的报名+类名,则ShapeFactory中就可以用反射构造类来创建具体的实例,这就和Spring的BeanFactory机制一样。

  2. 工厂方法模式:定义一个创建对象的抽象工厂类,由其子类,也就是具体的工厂实现类来决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。
    在这里插入图片描述
    示例:创建Circle和Rectangle,这两种形状各自有自己的工厂,调用者只需调用工厂基类的getShape()方法。

    public class FactoryMethodDemo
    {
    	static abstract class Shape
    	{
        	void draw() {
            	System.out.println("I am a default shape");
        	}
    	}
    	
    	static class Circle extends Shape
    	{
        	@Override
        	void draw()
        	{
            	System.out.println("I am a circle.");
        	}
    	}
    
    	static class Rectangle extends Shape
    	{
        	@Override
        	void draw()
        	{
            	System.out.println("I am a rectangle.");
        	}
    	}
    	
    	static abstract class ShapeFactory
    	{
        	Shape getShape()
        	{
            	return null;
        	}
    	}
    
    	static class CircleFactory extends ShapeFactory
    	{
        	@Override
        	Shape getShape()
        	{
            	return new Circle();
        	}
    	}
    
    	static class RectangleFactory extends ShapeFactory
    	{
        	@Override
        	Shape getShape()
        	{
            	return new Rectangle();
        	}
    	}
    
    	public static void main(String[] args)
    	{
        	ShapeFactory shapeFactory = new CircleFactory();
        	Shape shape = shapeFactory.getShape();
        	shape.draw();
    	}
    }
    

    工厂方法模式较简单工厂模式而言,扩展性更好,如果需要添加一种新的形状,只需要添加相应的形状类和工厂类,即可在main方法中使用新的工厂类来创建新的形状。

  3. 抽象工厂模式:提供一个用于创建相关或有依赖关系对象簇的接口,而无需指明具体的类。抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合,它将工厂分为抽象工厂类和具体的工厂子类,抽象工厂类需要调用多个具体的工厂子类生产出多个子对象进行组合,形成最终想要的产品。这里所说的抽象工厂类和工厂方法模式中提到的抽象工厂类不同。
    在这里插入图片描述
    示例:Color和Shape关系密切,所以需要提供抽象接口,将获取Color和Shape组合在一起。这里ShapeFactory和ColorFactory向左的实现可以是简单工厂模式,也可以是工厂方法模式。这里使用简单工厂模式。

    public class AbstractFactoryDemo
    {
    	static abstract class Shape
    	{
        	void draw() {
            	System.out.println("I am a default shape");
        	}
    	}
    
    	static class Circle extends Shape
    	{
        	@Override
        	void draw()
        	{
            	System.out.println("I am a circle.");
        	}
    	}
    
    	static class Rectangle extends Shape
    	{
        	@Override
        	void draw()
        	{
            	System.out.println("I am a rectangle.");
        	}
    	}
    
    	static abstract class Color
    	{
        	void fill() {
            	System.out.println("I am default color");
        	}
    	}
    
    	static class Red extends Color
    	{
        	@Override
        	void fill()
        	{
            	System.out.println("I am red.");
        	}
    	}
    
    	static class Yellow extends Color
    	{
        	@Override
        	void fill()
        	{
            	System.out.println("I am yellow.");
        	}
    	}
    
    	static abstract class AbstractFactory
    	{
        	Shape getShape(String shapeType)
        	{
            	return null;
        	}
        	
        	Color getColor(String colorType)
        	{
            	return null;
        	}
    	}
    
    
    	static class ShapeFactory extends AbstractFactory
    	{
        	@Override
        	Shape getShape(String shapeType)
        	{
            	if (shapeType.equals("circle"))
            	{
                	return new Circle();
            	}
            	else if (shapeType.equalsIgnoreCase("rectangle"))
            	{
                	return new Rectangle();
            	}
            	return null;
        	}
    	}
    
    	static class ColorFactory extends AbstractFactory
    	{
        	@Override
        	Color getColor(String colorType)
        	{
            	if (colorType.equalsIgnoreCase("red"))
            	{
                	return new Red();
            	}
            	else if (colorType.equalsIgnoreCase("yellow"))
            	{
                	return new Yellow();
            	}
            	return null;
        	}
    	}
    
    	// 额外又用了一次工厂,这里参考了菜鸟教程中关于抽象工厂的示例。
    	static class FactoryProducer
    	{
        	static AbstractFactory getFactory(String choice)
        	{
            	if (choice.equalsIgnoreCase("shape"))
            	{
                	return new ShapeFactory();
            	}
            	else if (choice.equalsIgnoreCase("color"))
            	{
                	return new ColorFactory();
            	}
            	return null;
        	}
    	}
    
    	public static void main(String[] args)
    	{
        	String shapeType = "circle";
        	String colorType = "red";
        	AbstractFactory shapeFactory = FactoryProducer.getFactory("shape");
        	Shape shape = shapeFactory.getShape(shapeType);
        	shape.draw();
        	AbstractFactory colorFactory = FactoryProducer.getFactory("color");
        	Color color = colorFactory.getColor(colorType);
        	color.fill();
    	}
    }
    

    这种方法的特点是需要了解产品的构造,才能更好的实现抽象工厂类。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值