工厂模式优点:
- 可以使代码结构清晰,有效地封装变化
- 对调用者屏蔽具体的产品类。
- 降低耦合度
使用场景与使用效果:
在任何需要生成关系复杂的对象的地方,都可以使用工厂模式进行解耦 ,实现高聚合,使得代码遵守开闭原则。降低后序添加代码的成本,提高扩展性。
原始运营模式(提供简单工厂与工厂方法模式优化)
未使用工厂模式前的计算机实现案例,使用的时候需要使用者一个一个是实例化使用的运算方法,将运算类型比作商品,那么该商品是由使用者自己生产并非工厂生产。
操作计算方法main函数:
public class Test {
public static void main(String[] args) {
SubOperation sub = new SubOperation();
sub.setValue1(1);
sub.setValue2(2);
double result =sub.Operation();
System.out.println(result);
AddOperation add = new AddOperation();
add.setValue1(1);
add.setValue2(2);
double result1 =add.Operation();
System.out.println(result1);
}
}
计算器抽象类用于统一计算模式:
public abstract class AbstractOpration {
private double value1 = 0;
private double value2 = 0;
public double getValue1() {
return value1;
}
public void setValue1(double value1) {
this.value1 = value1;
}
public double getValue2() {
return value2;
}
public void setValue2(double value2) {
this.value2 = value2;
}
public abstract double Operation();
}
描述两个实际计算类:
- 加法:
public class AddOperation extends AbstractOpration{
@Override
public double Operation() {
return getValue1()+getValue2();
}
}
- 减法:
public class SubOperation extends AbstractOpration{
@Override
public double Operation() {
// TODO Auto-generated method stub
return getValue1()-getValue2();
}
}
简单工厂模式
图解:
- 简单工厂模式中,存在一个工厂,他有当前所以产品的选择集合。使用产品类继承产品接口(也可以是产品的抽象类)。
- 使用工厂模式后产品交给工厂生产,需求者只需要告知需要什么产品变可以获得。
添加工厂:
public class Factory {
public AbstractOpration factoryMoth(String params) {
AbstractOpration result = null;
switch (params) {
case "add":
result = new AddOperation();
break;
case "sub":
result = new SubOperation();
break;
default:
throw new RuntimeException("不支持这种运算");
}
return result;
}
}
一个工厂中包含所有商品类型
需求者main函数:
public class OperationTest {
public static void main(String[] args) {
AbstractOpration opration = new Factory().factoryMoth("add");
opration.setValue1(1);
opration.setValue2(2);
System.out.println(opration.Operation());
}
}
告知需要add,工厂加工完毕后可以使用
简单工厂模式的缺陷:
由于只有一个工厂,可见代码的耦合性很高,如果新增一个商品,我们不仅要添加新商品还有在Factory工厂的添加新商品的代码。不符合代码的开闭原则。
工厂方法模式
图解:
- 工厂方法模式将工厂接口化,形成一个产品一个工厂。
工厂接口化:
public interface IFactory {
public AbstractOpration cerateFactory();
}
加法工厂:
public class AddFactory implements IFactory{
@Override
public AbstractOpration cerateFactory() {
return new AddOperation();
}
}
减法工厂:
public class SubFactory implements IFactory{
@Override
public AbstractOpration cerateFactory() {
return new SubOperation();
}
}
需求者mian函数:
public class OprationTest {
public static void main(String[] args) {
AbstractOpration opration = new AddOperation();
opration.setValue1(1);
opration.setValue2(2);
System.out.println(opration.Operation());
AbstractOpration opration2 = new SubOperation();
opration2.setValue1(2);
opration2.setValue2(1);
System.out.println(opration2.Operation());
}
}
工厂方法模式优点:
代码高度聚合,添加新产品只需要添加新工厂不需要修改原来的代码类。
扩展性高
不需知道产品实现,调用者只需要知道产品接口
工厂方法模式缺点:
通过观察可以发现,新的产品加入必定要有新的工厂,那么如果产品数量大,那么就会形成类爆炸。
类成倍增加
代码量大
使用场景:
日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。
数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。
设计一个连接服务器的框架,需要三个协议,“POP3”、“IMAP”、“HTTP”,可以把这三个作为产品类,共同实现一个接口。
比如 Hibernate 换数据库只需换方言和驱动就可以
抽象工厂模式
图解:
抽象工厂模式是工厂方法模式的优化,工厂方法模式工厂与产品是一对一,抽象工厂模式与产品的关系为一对多。
产品接口:
public interface IProductIpad {
public void Ipad();
}
public interface IProductPhone {
public void Phone();
}
产品实现:
public class XMPhone implements IProductPhone{
@Override
public void Phone() {
System.out.println("小米手机");
}
}
public class XMIpad implements IProductIpad{
@Override
public void Ipad() {
System.out.println("小米平板");
}
}
public class HWIpad implements IProductIpad{
@Override
public void Ipad() {
System.out.println("华为平板");
}
}
public class HWPhone implements IProductPhone{
@Override
public void Phone() {
System.out.println("华为手机");
}
}
工厂接口:
public interface IFactory {
public IProductPhone createPhone();
public IProductIpad createIpad();
}
工厂实现:
public class HWFactory implements IFactory{
@Override
public IProductPhone createPhone() {
return new HWPhone();
}
@Override
public IProductIpad createIpad() {
return new HWIpad();
}
}
public class XMFactory implements IFactory{
@Override
public IProductPhone createPhone() {
return new XMPhone();
}
@Override
public IProductIpad createIpad() {
return new XMIpad();
}
}
生产:
public class Test {
public static void main(String[] args) {
IFactory factory = new HWFactory();
IProductIpad ipad = factory.createIpad();
ipad.Ipad();
IProductPhone phone = factory.createPhone();
phone.Phone();
}
}
优点:
在增加新产品时,不用修改产品的代码,符合开闭原则。
缺点:
在增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了“开闭原则”。
工厂模式退化
- 抽象工厂模式方法中的每个工厂只生产有一个产品时,退化为工厂方法模式。
- 工厂方法模式中将所有的工厂合并为一个工厂时,退化为简单工厂模式。
现实中使用的工厂模式:
后端Spring家族中使用SpringIOC,特点各各接口实现类统一由管家管理
JDK 的 Calendar 使用了简单工厂模式