工厂相关模式有哪几种?
如果之前有人这样问我,我肯定答不上来,因为一直疲于增删改查的编码,而对这些硬核知识看不见!但在再次求职面试的时候,肯定会在这方面吃亏!那还等什么,现在就来撸清楚。
工厂相关模式主要有简单工厂、工厂方法、抽象工厂三种模式,有同学可能会说工厂方法不属于GoF的23种设计模式吧?但是为了代码理解,也把简它算在其内。
一、简单工厂模式,主要解决什么问题呢?它是如何解决的?
1.定义一个接口
/**
* 1.定义一个形状接口
* @author 程就人生
* @Date
*/
public interface IShape {
void draw();
}
2.扩展接口的实现类两个;
/**
* 2.创建实现接口的现类-1,长方形
* @author 程就人生
* @Date
*/
public class Rectangle implements IShape{
@Override
public void draw() {
System.out.println(" Rectangle ");
}
}
/**
* 2.创建实现接口的现类-2,正方形
* @author 程就人生
* @Date
*/
public class Square implements IShape{
@Override
public void draw() {
System.out.println(" Square ");
}
}
3.定义工厂类;
/**
* 3.创建工厂类
* 将创建细节隐藏在创建工厂类里
* @Date
*/
public class ShapeFactory {
// 写法 1
// public IShape getShape(String shapeType){
// if(shapeType == null){
// return null;
// }
// if(shapeType.equalsIgnoreCase("RECTANGLE")){
// return new Rectangle();
// } else if(shapeType.equalsIgnoreCase("SQUARE")){
// return new Square();
// }
// return null;
// }
// 写法2:采用反射机制
// public IShape getShape(String shapeType){
// try {
// return (IShape)Class.forName(shapeType).newInstance();
// } catch (InstantiationException e) {
// e.printStackTrace();
// } catch (IllegalAccessException e) {
// e.printStackTrace();
// } catch (ClassNotFoundException e) {
// e.printStackTrace();
// }
// return null;
// }
// 写法3
public IShape getShape(Class<? extends IShape> clazz){
try {
return clazz.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}
4.应用;
public static void main(String[] argo){
//4. 测试简单工厂
ShapeFactory shapeFactory = new ShapeFactory();
//通过传递类型信息来获取实体类的对象
// 写法1
//IShape shape1 = shapeFactory.getShape("RECTANGLE");
// 写法2
//IShape shape1 = shapeFactory.getShape("com.example.factory1.Rectangle");
// 写法3
IShape shape1 = shapeFactory.getShape(Rectangle.class);
//获取 Rectangle 的对象,并调用它的 draw 方法
shape1.draw();
//获取 Square 的对象,并调用它的 draw 方法
//IShape shape2 = shapeFactory.getShape("SQUARE");
//IShape shape2 = shapeFactory.getShape("com.example.factory1.Square");
IShape shape2 = shapeFactory.getShape(Square.class);
//调用 Square 的 draw 方法
shape2.draw();
}
这段代码的意思是:要创建一个长方形或正方形,实例化哪个接口,通过工厂类传递一个字符串或类名就可以了,实例化是在工厂类里面做的,这对客户端是不可见的。
最后,输出结果:
Rectangle
Square
二、工厂方法,它和简单工厂的区别在哪里呢?它解决什么问题?它又是如何解决的?
1.定义一个形状接口;
/**
* 1.定义一个形状接口
* @author 程就人生
* @Date
*/
public interface IShape {
void draw();
}
2.扩展接口的实现类两个;
/**
* 2.创建实现接口的现类-1,长方形
* @author 程就人生
* @Date
*/
public class Rectangle implements IShape{
@Override
public void draw() {
System.out.println(" Rectangle ");
}
}
/**
* 2.创建实现接口的现类-2,正方形
* @author 程就人生
* @Date
*/
public class Square implements IShape{
@Override
public void draw() {
System.out.println(" Square ");
}
}
3.定义一个工厂接口;
/**
* 3.定义一个工厂接口
* @Date
*/
public interface IShapeFactory {
// 类的实例化推迟到子类
IShape create();
}
4.工厂接口的实现类两个;
/**
* 4.实现工厂接口
* @Date
*/
public class RectangleFactory implements IShapeFactory{
@Override
public IShape create() {
return new Rectangle();
}
}
/**
* 4.实现工厂接口
* @Date
*/
public class SquareFactory implements IShapeFactory{
@Override
public IShape create() {
return new Square();
}
}
5.应用;
public static void main(String[] argo){
// 5.测试工厂方法
IShapeFactory shapeFactory = new RectangleFactory();
shapeFactory.create().draw();
IShapeFactory shapeFactory2 = new SquareFactory();
shapeFactory2.create().draw();
}
这段代码的意思是:要创建一个长方形或正方形,通过声明工厂接口,实例化工厂实现类,来创建的。创建过程在工厂实现类中,因此便于产品的扩展。
它和简单工厂的区别在于,工厂类变成了工厂接口,并扩展了工厂类,实例化放在了工厂接口的子类里做。
最后,测试结果:
Rectangle
Square
三、抽象工厂,真的很抽象,网友们对这个模式的写法很不统一****,所以说它是最复杂的创建型模式。
为什么说它复杂呢?因为它涉及到产品族和产品等级,它们是不同维度的扩展,到底如何扩展呢,看代码;
1.定义一个形状的接口;
/**
* 1.定义一个形状接口
* @author 程就人生
* @Date
*/
public interface IShape {
void draw();
}
2. 定义一个颜色接口;
/**
* 2.定义一个颜色接口
* @author 程就人生
* @Date
*/
public interface IColor {
void fill();
}
3.定义抽象工厂类;
/**
* 3.抽象工厂
* @author 程就人生
* @Date
*/
public abstract class AbstractFactory {
// 创造形状
public abstract IShape createShape();
// 涂颜色
public abstract IColor createColor();
}
4.创建形状接口的一个或多个实现类,这里只写一个;
/**
* 4.创建形状接口的实现类-1,长方形
* @author 程就人生
* @Date
*/
public class Rectangle implements IShape{
@Override
public void draw() {
System.out.println(" draw rectangle ");
}
}
5.创建颜色接口的一个或多个实现类,这里只写一个;
/**
* 5. 创建颜色接口的实现类
* @author 程就人生
* @Date
*/
public class Red implements IColor{
@Override
public void fill() {
System.out.println(" fill red ");
}
}
6.抽象工厂的一个或多个实现类,这里只写一个;
/**
* 6.绘制红色长方形的工厂,扩展了抽象工厂
* @author 程就人生
* @Date
*/
public class RedRectangleFactory extends AbstractFactory {
@Override
public IShape createShape() {
return new Rectangle();
}
@Override
public IColor createColor() {
return new Red();
}
}
7.应用;
public static void main(String[] argo){
// 绘制红色长方形
AbstractFactory redRectangle = new RedRectangleFactory();
redRectangle.createShape().draw();
redRectangle.createColor().fill();
}
以上代码的意思是:通过一个抽象工厂的实现类,绘制红色长方形,颜色和形状有各自的接口和实现类。这里假设每种形状为一个产品族,每种颜色则为一系列产品,那么每个根据每个颜色 + 形状就可获取某一个产品族下的某一个系列产品。
测试结果:
draw rectangle
fill red
模式了解只是第一步,多看几遍快点应用起来吧!
感觉有用,请关注同名公众号吧~!
网友评论