23种设计模式-创建型模式-工厂模式(包括工厂方法模式和抽象工厂模式)

1.为什么要有工厂模式:

一个对象相关的职责通常有三类:对象本身所具有的职责、创建对象的职责和使用对象的职责。
用工厂模式就是为了:

  1. 把对象的创建和使用的过程分开
  2. 降低代码重复
  3. 降低维护成本

2. 工厂模式的分类:

(1)简单工厂(Simple Factory)模式,又称静态工厂方法模式(Static Factory Method Pattern),不属于23种。
(2)工厂方法(Factory Method)模式,又称多态性工厂(Polymorphic Factory)模式或虚拟构造子(Virtual Constructor)模式;
(3)抽象工厂(Abstract Factory)模式,又称工具箱(Kit 或Toolkit)模式。

3. 开源框架中的使用

  1. Spring框架中BeanFactory接口提供了getBean方法,在AbstractBeanFactory中实现了该方法。
  2. SqlSessionFactory获得一个SqlSession

4.简单工厂模式

角色:
工厂(Factory)角色 、抽象产品(Product)角色 、具体产品(Concrete Product)角色

Circle、Rectangle和Square实现了Shape接口

public class ShapeFactory {
    // 使用 getShape 方法获取形状类型的对象
    public static Shape getShape(String shapeType) {
        if (shapeType == null) {
            return null;
        }
        if (shapeType.equalsIgnoreCase("CIRCLE")) {
            return new Circle();
        } else if (shapeType.equalsIgnoreCase("RECTANGLE")) {
            return new Rectangle();
        } else if (shapeType.equalsIgnoreCase("SQUARE")) {
            return new Square();
        }
        return null;
    }
}

反射改进:

/**
 * 利用反射解决简单工厂每次增加新了产品类都要修改产品工厂的弊端
 */
public class ShapeFactory2 {
    public static Object getClass(Class<? extends Shape> clazz) {
        Object obj = null;
        try {
            obj = Class.forName(clazz.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return obj;
    }
}

5. 工厂方法模式

角色:
抽象工厂(Abstract Factory)角色、具体工厂(Concrete Factory)角色 、抽象产品(AbstractProduct)角色、具体产品(Concrete Product)角色
圆形工厂类:

public class CircleFactory implements Factory {
    @Override
    public Shape getShape() {
        return new Circle();
    }
}

长方形工厂类、正方形工厂类略。
与抽象工厂模式区别:工厂方法模式每一个具体产品对应一个具体的产品工厂类,而抽象工厂模式是一个具体工厂生产多个具体的产品(产品间有关系,所以有多个生产不同抽象产品的抽象方法)。

6. 抽象工厂模式

角色:
抽象工厂(Abstract Factory)角色、具体工厂(Concrete Factory)角色 、抽象产品(AbstractProduct)角色、具体产品(Concrete Product)角色
拿吃鸡类游戏种的AK、M16A4、5.56mm子弹、7.62子弹来举个例子:

public abstract class Gun {
	String gunName;
    public Gun(String gunName) {
		this.gunName = gunName;
	}
	public abstract void shooting(Bullet bullet);
}

public class AK extends Gun {
	public AK() {
		super("AK");
	}
	@Override
	public void shooting(Bullet bullet) {
		System.out.println(super.gunName+"用"+bullet.bulletName+"单发射击");
	}
}

public class M16A4 extends Gun {
	public M16A4() {
		super("M16A4");
	}
	@Override
	public void shooting(Bullet bullet) {
		System.out.println(super.gunName+"用"+bullet.bulletName+"三连发射击");
	}
}

public abstract class Bullet {
	public String bulletName;
    public Bullet(String bulletName) {
		this.bulletName = bulletName;
	}
}

public class Bullet556 extends Bullet {
	public Bullet556() {
		super("5.56mm子弹");
	}
}

public class Bullet762 extends Bullet {
	public Bullet762() {
		super("7.62mm子弹");
	}
}

public interface Factory {
    public Gun produceGun();
    public Bullet produceBullet();
}

public class AK_Factory implements Factory{
    @Override
    public Gun produceGun() {
        return new AK();
    }
    @Override
    public Bullet produceBullet() {
        return new Bullet762();
    }
}

public class M16A4_Factory implements Factory{
    @Override
    public Gun produceGun() {
        return new M16A4();
    }
    @Override
    public Bullet produceBullet() {
        return new Bullet556();
    }
}

public class Test {
	public static void main(String[] args) {
		Factory f=new AK_Factory();
		Bullet bullet = f.produceBullet();
		Gun gun = f.produceGun();
		gun.shooting(bullet);
		
		f=new M16A4_Factory();
		bullet = f.produceBullet();
		gun = f.produceGun();
		gun.shooting(bullet);
	}
}

运行输出结果:

AK用7.62mm子弹单发射击
M16A4用5.56mm子弹三连发射击

深入了解工厂模式的作用可以看这篇博文:https://blog.csdn.net/qq_22771739/article/details/86572282

猜你喜欢

转载自blog.csdn.net/qq_22771739/article/details/86572272