一开始学工厂模式的时候一点也不明白,看了很多文章问了很多人为什么要使用工厂模式?为什么工厂模式就是解耦?看了几天有了点个人的理解,故写下来防止以后忘记。如果有什么不对或者理解不到位的地方,希望能告知。
1.工厂模式的本质
工厂模式又称为创建模式,它是建对象的一种最佳方式。工厂模式的本质就是用工厂方法代替new操作创建一种实例化对象的方式。一句话中总结就是方便创建 同种类型接口产品 的 复杂对象。
举例:实例化一个对象sample 一般会想到的方法是通过构造器来创建sample s=new sample();但是在实际情况下最好不要这样做,如果sample类的在实例化的时候需要初始化参数而这些参数需要别的类的信息,这样你new的话会增加你代码的耦合度,不利于维护。所以我们就需要将创建实例的工作和使用使用实例的工作分开,即:使用工厂方法创建实例的工作封装起来。这样我们在需要调用对象的时候就不需要关心那些复杂的实例化问题。
接下来介绍具体有哪些工厂
1.简单工厂模式(静态工厂模式)
简单工厂模式中有抽象产品类:用来定义具体产品的共有属性,工厂类则负责生产具体产品。
直接看代码:定义一个抽象产品类形状类Shape
abstract class Shape(){
public abstract void shape();
定义具体产品:
class Circle extends Shape{
public void shape(){
System.out.println("圆形");
}
}
class Rectangle extends Shape{
public void shape(){
System.out.println("矩形");
}
}
class Triangle extends Shape{
public void shape(){
System.out.println("三角形");
}
}
定义一个工厂生产具体产品
public class ShapeFactory{
public static Shape getshape(String sh){
if(sh.equals("圆形")){
return new Circle();
}else if(sh.equals("矩形")){
return new Rectangle();
}else if(sh.equals("三角形")){
return new Triangle();
}else {
return null;
}
}
public static void main(String args[]){
ShapeFactory.getshape("圆形").shape();
}
}
output:圆形
- 从简单工厂中我们可以看出使用一个静态方法将实例化的创建和使用分离开。我们只需要调用方法传递参数就可以获得我们需要的对象。
- 缺点:我们不难看出如果我们想要增加一个形状类的产品不仅需要添加一个导出类而且我们必须要修改静态方法getshape,这样就违背了开闭原则(对于扩展是开放的,对于修改是封闭的)
这时我们就可以想我们是不是可以将工厂也抽象出来?让具体工厂来负责创建具体产品对象,就上面的例子我们可以创建一个圆形的具体工厂让他只负责创建圆形产品对象,这样当我们想要增加一个产品的时候我们就只需要增加对应的工厂就行了,不需要修改其他东西。接下来我们说说工厂模式
2.工厂模式
就如上面所说的我们先了解工厂模式的具体概念:
- 抽象工厂:工厂模式的核心,提供一个创建对象的接口,任何需要创建对象的具体工厂都要实现这个接口。
- 具体工厂:实现抽象工厂接口的类,受到调用者的调用从而创建对象。
- 抽象产品:工厂方法模式所创建的对象的超类。也就是所有具体产品的共同父类。
- 具体产品:实现抽象工厂接口的类。工厂模式中所有创建的对象都是具体产品的实例。
抽象产品Shape
abstract class Shape {
public abstract void shape();
}
具体产品:
class Circle extends Shape{
public void shape(){
System.out.println("圆形");
}
}
class Rectangle extends Shape{
public void shape(){
System.out.println("矩形");
}
}
class Triangle extends Shape{
public void shape(){
System.out.println("三角形");
}
}
抽象工厂:
abstract class ShapeFactory{
public abstract Shape CreatShape();
}
具体工厂:
class CircleFactory extends ShapeFactory{
public Shape CreatShape(){
return new Circle();
}
}
class RectangleFactory extends ShapeFactory{
public Shape CreatShape(){
return new Rectangle();
}
}
class TriangleFactory extends ShapeFactory{
public Shape CreatShape(){
return new Triangle();
}
}
测试:
public class ShapeFactoryDemo{
public static void getshape(ShapeFactory sha){
sha.CreatShape().shape();
}
public static void main(String args[]){
getshape(new CircleFactory());
}
}
如上所示:即使我们增加一个新的形状类,我们也只需要增加相应的工厂类,不需要修改代码的任何方法。当我们需要这个新产品的时候我们只需要getshap(new 新的工厂类),其他的我们不用去关心,不需要了解方法的实现,对象是如何创建的,我们只需要调用方法就行了——良好的封装性。
优点:
- 良好的封装性:如上面所说。
- 可以是代码结构变得清晰,有效的封装变化,通常new一个具体类是很复杂多变的,通过工厂方法将new的过程封装在具体工厂的方法中,调用者无须知道实例化的过程,只需要调用方法就可以得到自己想要的产品。
有很多文章说工厂模式就是一种典型的解耦模式,对于这点我不是很清楚:抽象产品和抽象工厂之间是没有耦合问题,但是抽象工厂将耦合问题传给了具体工厂啊!具体工厂中的方法就是new出具体产品的实例,他们之间任然有耦合。这点我不是很明白,或许我的理解有问题。
- 用到工厂模式的地方:
1.创建对象的复杂度高。
2.创建对象时需要增加依赖关系,就是说需要某些信息而这些信息不在复合类中。
3.当系统需要比较好的延展性的时候。