Java设计模式之工厂模式

简单工厂模式

 简单工厂模式是一种创建型模式,它不属于23种设计模式。简单工厂模式是通过一个类(工厂类)来创建其他类的实例,其他类都有一个共同的父类。实例的创建是通过向工厂类传入不同的参数来创建不同的对象。

简单工厂模式需要的角色。

具体工厂就是那个创建类的类,抽象产品就是公共的父类,创建的实例就是具体工厂的实例。

 

  • 一个抽象产品接口
  • 多个具体产品类
  • 一个具体工厂类

 

具体实例:

水果类接口

package simpleFactory;

public interface Fruit {
	//采摘方法
	public void get();
}

实现水果接口

苹果类

package simpleFactory;

public class Apple implements Fruit {
	//采摘苹果
	public void get() {
		System.out.println("采摘苹果");
	}
}

香蕉类

package simpleFactory;

public class Banana implements Fruit {
	//采摘香蕉
	public void get() {
		System.out.println("采摘香蕉");
	}
}

工厂类

package simpleFactory;

public class FruitFactory {
	//采集水果
	public static Fruit getFruit(String type) {
		if(type.equals("apple")) {
			return new Apple();
		}else if(type.equals("banana")){
			return new Banana();
		}else {
			System.out.println("输入有误");
			return null;
		}
	}
}

client

package simpleFactory;

public class Client {
	public static void main(String[] args) {
		Fruit apple = FruitFactory.getFruit("apple");
		Fruit banana = FruitFactory.getFruit("banana");
//		Fruit other = FruitFactory.getFruit("pear");
		apple.get();
		banana.get();
//		other.get();
	}
}

 运行结果

采摘苹果
采摘香蕉

简单工厂模式存在的弊端:

  1. 不同类的实例对象的新建逻辑都在一个类中,不能体现类的“高内聚”。
  2. 当有新的产品需要生产时,需要改动工厂类的代码,不符合“开放-封闭 ”原则。

简单工程就可以理解为:一个工厂,不同的产品,同一个工厂可以根据参数生产不同的产品。一句话:按需生产。需就是参数。

工厂方法模式 

工厂方法模式是一种创建型模式,也叫多态工厂模式(运行时工厂呈现出一种多态),是设计模式中的一种,工厂方法模式的工厂类不再是一个具体的类,而是一个工厂接口,每个产品的生产交给实现它的具体的子类来完成,它只提供了生产产品的规范,具体的怎么生产由子类决定,在要扩展新的产品时,就实现一个新的产品工厂,扩展性较好。

 工厂方法模式需要的角色

 

  • 一个抽象产品接口 
  • 多个具体产品类
  • 一个抽象工厂接口(对实现同一个抽象接口的类生产)
  • 多个具体工厂类

 模型图

 

实例

抽象工厂

package factoryMethod;

public interface FruitFactory {
	public Fruit getFruit();
}

抽象工厂实现类

package factoryMethod;

public class AppleFactory implements FruitFactory {

	@Override
	public Fruit getFruit() {
		
		return new Apple();
	}

}
package factoryMethod;

public class BananaFactory implements FruitFactory {

	@Override
	public Fruit getFruit() {
		
		return new Banana();
	}

}

client

package factoryMethod;

public class Client {
	public static void main(String[] args) {
		FruitFactory factory = null;
		Fruit fruit = null;
		
		//苹果工厂生产苹果
		factory = new AppleFactory();
		fruit = factory.getFruit();
		fruit.get();
		
		//香蕉工厂生产香蕉
		factory = new BananaFactory();
		fruit =factory.getFruit();
		fruit.get();
	}
	
}

结果

采摘苹果
采摘香蕉

 

1,高内聚,每个工厂只有一种对象的实例化逻辑,代码清晰。

2,扩展性好,生产一种新的产品时不需要修改原来的工厂,只需新建一个生产该产品的工厂类即可,符合“开放-封闭”原则。

简单理解:多个工厂,多个产品类,不同的工厂可以生产不同的产品(例如:手机工厂生产手机,mp3工厂生产mp3) 

抽象工厂模式 

抽象工厂模式与工厂方法模式有相似之处,都是通过不同的工厂生产不同的产品,担关注点又有所不同。工厂方法模式关注生产不同族的商品(例如:苹果和香蕉,汽车与火车)抽象工厂的关注点在于不同的工厂可以生产同一个产品族的不同产品(例如苹果的大和小,不同品牌的笔记本)这里引用https://www.cnblogs.com/geek6/p/3951677.html关于抽象工厂模式的阐释。 

工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。   
一个抽象工厂类,可以派生出多个具体工厂类。   
每个具体工厂类只能创建一个具体产品类的实例。

抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。   
一个抽象工厂类,可以派生出多个具体工厂类。   
每个具体工厂类可以创建多个具体产品类的实例,也就是创建的是一个产品线下的多个产品。   
    
区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。   
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
工厂方法创建 "一种" 产品,他的着重点在于"怎么创建",也就是说如果你开发,你的大量代码很可能围绕着这种产品的构造,初始化这些细节上面。也因为如此,类似的产品之间有很多可以复用的特征,所以会和模版方法相随。 

抽象工厂需要创建一些列产品,着重点在于"创建哪些"产品上,也就是说,如果你开发,你的主要任务是划分不同差异的产品线,并且尽量保持每条产品线接口一致,从而可以从同一个抽象工厂继承。

需要的角色

  • 多个抽象产品类
  • 一个抽象工厂接口(对实现不同抽象产品接口的类生产)
  • 多个具体工厂类

 产品图

这里的ProductA的子类1和子类2是属于同一产品族的,ProductB的子类1和子类2也是同一产品族(就如同联想笔记本和hp笔记本,还有大众帕萨特的高配车型和低配车型,铅笔的粗铅笔和细铅笔)

 

工厂图

Factory关注的不再是怎么生产产品,而是生产什么,在工厂方法模式中factory的不同子类生产的只是一种产品,而在抽象工厂模式中不同的子类生产不同的产品,就像下图Factory1可以生产产品A也可以生产产品B,但不同的Factory生产的同一类产品是不同的,就是说Facory1和Factory2生产的ProductA属于不同类的产品,就像(工厂1和工厂2都是生产笔记本电脑的厂商,虽然笔记本电脑都属于笔记本电脑类,但是他们生产不同品牌的电脑,工厂1生产联想,工厂2生产hp)

 

 这里实例说明一下

抽象产品接口

package stractFactory;

public interface Fruit {
	//采摘方法
	public void get();
}

实现产品接口的抽象类 

package stractFactory;

public abstract class Apple implements Fruit {
	//采摘苹果
	public abstract void get();
}
package stractFactory;

public abstract class Banana implements Fruit {
	//采摘香蕉
	public abstract void get();
}

实现抽象类的具体类

 

package stractFactory;

public class BigApple extends Apple {

	@Override
	public void get() {
		System.out.println("大苹果");
	}

}
package stractFactory;

public class SmallApple extends Apple {

	@Override
	public void get() {
		System.out.println("小苹果");
	}

}
package stractFactory;

public class BigBanana extends Banana {

	@Override
	public void get() {
		System.out.println("大香蕉");
	}

}
package stractFactory;

public class SmallBanana extends Banana {

	@Override
	public void get() {
		System.out.println("小香蕉");
	}

}

抽象工厂接口

package stractFactory;

public interface FruitFactory {
	public Fruit getBanana();
	public Fruit getApple();
}

具体实现类

package stractFactory;

public class SmallFactory implements FruitFactory {

	@Override
	public Fruit getBanana() {
		return new SmallBanana();
	}

	@Override
	public Fruit getApple() {
		return new SmallApple();
	}
	
}
package stractFactory;

public class BigFactory implements FruitFactory {

	@Override
	public Fruit getBanana() {
		
		return new BigBanana();
	}

	@Override
	public Fruit getApple() {
		
		return new BigApple();
	}

}

client

package stractFactory;

public class MainClazz {

	public static void main(String[] args) {
		FruitFactory factory = null;
		
		factory = new BigFactory();
		factory.getApple().get();
		factory.getBanana().get();
		
		factory = new SmallFactory();
		factory.getApple().get();
		factory.getBanana().get();
	}

}

结果

大苹果
大香蕉
小苹果
小香蕉

从抽象工厂接口也可以看出,抽象工厂模式关注的是生产哪些产品而不是怎么生产,这里有点难理解,小编也要好好揣摩一下。 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1 目标检测的定义 目标检测(Object Detection)的任务是找出图像中所有感兴趣的目标(物体),确定它们的类别和位置,是计算机视觉领域的核心问题之一。由于各类物体有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具有挑战性的问题。 目标检测任务可分为两个关键的子任务,目标定位和目标分类。首先检测图像中目标的位置(目标定位),然后给出每个目标的具体类别(目标分类)。输出结果是一个边界框(称为Bounding-box,一般形式为(x1,y1,x2,y2),表示框的左上角坐标和右下角坐标),一个置信度分数(Confidence Score),表示边界框中是否包含检测对象的概率和各个类别的概率(首先得到类别概率,经过Softmax可得到类别标签)。 1.1 Two stage方法 目前主流的基于深度学习的目标检测算法主要分为两类:Two stage和One stage。Two stage方法将目标检测过程分为两个阶段。第一个阶段是 Region Proposal 生成阶段,主要用于生成潜在的目标候选框(Bounding-box proposals)。这个阶段通常使用卷积神经网络(CNN)从输入图像中提取特征,然后通过一些技巧(如选择性搜索)来生成候选框。第二个阶段是分类和位置精修阶段,将第一个阶段生成的候选框输入到另一个 CNN 中进行分类,并根据分类结果对候选框的位置进行微调。Two stage 方法的优点是准确度较高,缺点是速度相对较慢。 常见Tow stage目标检测算法有:R-CNN系列、SPPNet等。 1.2 One stage方法 One stage方法直接利用模型提取特征值,并利用这些特征值进行目标的分类和定位,不需要生成Region Proposal。这种方法的优点是速度快,因为省略了Region Proposal生成的过程。One stage方法的缺点是准确度相对较低,因为它没有对潜在的目标进行预先筛选。 常见的One stage目标检测算法有:YOLO系列、SSD系列和RetinaNet等。 2 常见名词解释 2.1 NMS(Non-Maximum Suppression) 目标检测模型一般会给出目标的多个预测边界框,对成百上千的预测边界框都进行调整肯定是不可行的,需要对这些结果先进行一个大体的挑选。NMS称为非极大值抑制,作用是从众多预测边界框中挑选出最具代表性的结果,这样可以加快算法效率,其主要流程如下: 设定一个置信度分数阈值,将置信度分数小于阈值的直接过滤掉 将剩下框的置信度分数从大到小排序,选中值最大的框 遍历其余的框,如果和当前框的重叠面积(IOU)大于设定的阈值(一般为0.7),就将框删除(超过设定阈值,认为两个框的里面的物体属于同一个类别) 从未处理的框中继续选一个置信度分数最大的,重复上述过程,直至所有框处理完毕 2.2 IoU(Intersection over Union) 定义了两个边界框的重叠度,当预测边界框和真实边界框差异很小时,或重叠度很大时,表示模型产生的预测边界框很准确。边界框A、B的IOU计算公式为: 2.3 mAP(mean Average Precision) mAP即均值平均精度,是评估目标检测模型效果的最重要指标,这个值介于0到1之间,且越大越好。mAP是AP(Average Precision)的平均值,那么首先需要了解AP的概念。想要了解AP的概念,还要首先了解目标检测中Precision和Recall的概念。 首先我们设置置信度阈值(Confidence Threshold)和IoU阈值(一般设置为0.5,也会衡量0.75以及0.9的mAP值): 当一个预测边界框被认为是True Positive(TP)时,需要同时满足下面三个条件: Confidence Score > Confidence Threshold 预测类别匹配真实值(Ground truth)的类别 预测边界框的IoU大于设定的IoU阈值 不满足条件2或条件3,则认为是False Positive(FP)。当对应同一个真值有多个预测结果时,只有最高置信度分数的预测结果被认为是True Positive,其余被认为是False Positive。 Precision和Recall的概念如下图所示: Precision表示TP与预测边界框数量的比值 Recall表示TP与真实边界框数量的比值 改变不同的置信度阈值,可以获得多组Precision和Recall,Recall放X轴,Precision放Y轴,可以画出一个Precision-Recall曲线,简称P-R
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值