工厂模式是Java中最常用的设计模式之一。
工厂模式适用的一些场景(不仅限于以下场景):
1. 对象的创建过程/实例化准备工作很复杂,需要初始化很多参数、查询数据库等。
2. 类本身有好多子类,这些类的创建过程在业务中容易发生改变,或者对类的调用容易发生改变。
第一步:创建“Shape”的接口
//创建一个接口Shape.java
public interface Shape{
//有一个绘制的方法
void draw();
}
第二步:创建实现相同接口的具体类,包括“Circle”,“Square”,“Rectangle”,如下:
package com.cn.xj.tool.Factory;
/**
* Created by xuanyl1111 on 2019/8/25.
*/
public class Rectangle implements Shape {
@Override
public void draw(){
System.out.println("Inside Rectangle::draw() method.");
}
}
第三步:创建工厂,根据给定的信息生成具体的类的对象
ShapeFactory.java
// "形状"工厂类
public class ShapeFactory{
public Shape getShape(String shapeType){
if (shapeType == null){
return null;
}
if (shapeType.equalsIgnoreCase("CIRCLE")) {
return new Circle();
}else if (shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}else if (shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
}
return null;
}
}
第四步:使用工厂通过传递类型等信息,来获取具体类的对象
package com.cn.xj.tool.Factory;
public class FactoryPatternDemo {
public static void main(String[] args) {
//创建一个工厂类的对象
ShapeFactory shapeFactory = new ShapeFactory();
//使用工厂,通过传递“类型“等信息
//拓展: “父类引用指向子类的对象”
Shape shape1 = shapeFactory.getShape("CIRCLE");
shape1.draw();
Shape shape2 = shapeFactory.getShape("Square");
shape2.draw();
Shape shape3 = shapeFactory.getShape("Rectangle");
shape3.draw();
}
}
拓展: “ 父类引用指向子类的对象 ”
当这样定义时: Animal a = new Cat();
表示定义了一个Animal类型的引用,指向新建的Cat类型的对象。由于Cat是继承自它的父类Animal,所以Animal类型的引用是可以指向Cat类型的对象的。那么这样做有什么意义呢?因为子类是对父类的一个改进和扩充,所以一般子类在功能上较父类更强大,属性较父类更独特, 定义一个父类类型的引用指向一个子类的对象既可以使用子类强大的功能,又可以抽取父类的共性。
所以,父类类型的引用可以调用父类中定义的所有属性和方法,而对于子类中定义而父类中没有的方法,它是无可奈何的; 同时,父类中的一个方法只有在父类中定义而在子类中没有重写的情况下,才可以被父类类型的引用调用; 对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态连接。也可以叫做动态绑定。
第五步:验证