工厂模式
工厂模式就有三种,它们分别是简单工厂模式(并不在23中模式之中),工厂方法模式以及抽象工厂模式,其中我们通常所说的工厂模式指的是工厂方法模式,工厂方法模式是日常开发中使用频率最高的一种设计模式。
1、简单工厂模式
简单工厂模式其实并不算是一种设计模式,更多的时候是一种编程习惯。
定义:定义一个工厂类,根据传入的参数不同返回不同的实例,被创建的实例具有共同的父类或接口。
适用场景:其实由定义也大概能推测出其使用场景,首先由于只有一个工厂类,所以工厂类中创建的对象不能太多,否则工厂类的业务逻辑就太复杂了,其次由于工厂类封装了对象的创建过程,所以客户端应该不关心对象的创建。总结一下适用场景:
(1)需要创建的对象较少。
(2)客户端不关心对象的创建过程。
以上就是简单工厂模式简单工厂模式的适用场景,下面看一个具体的实例。
实例:
创建一个可以绘制不同形状的绘图工具,可以绘制圆形,正方形,三角形,每个图形都会有一个draw()方法用于绘图,不看代码先考虑一下如何通过该模式设计完成此功能。
由题可知圆形,正方形,三角形都属于一种图形,并且都具有draw方法,所以首先可以定义一个接口或者抽象类,作为这三个图像的公共父类,并在其中声明一个公共的draw方法。
public interface Shape { void draw(); }
这里定义成抽象类也是可以的,只不过接口是更高一级的抽象,所以习惯定义成接口,而且接口支持多实现,方便以后扩展。
下面就是编写具体的图形,每种图形都实现Shape 接口
圆形
public class CircleShape implements Shape { public CircleShape() { System.out.println( "CircleShape: created"); } @Override public void draw() { System.out.println( "draw: CircleShape"); } }
正方形
public class RectShape implements Shape { public RectShape() { System.out.println( "RectShape: created"); } @Override public void draw() { System.out.println( "draw: RectShape"); } }
三角形
public class TriangleShape implements Shape { public TriangleShape() { System.out.println( "TriangleShape: created"); } @Override public void draw() { System.out.println( "draw: TriangleShape"); } }
下面是工厂类的具体实现:
public class ShapeFactory { public static final String TAG = "ShapeFactory"; public static Shape getShape(String type) { Shape shape = null; if (type.equalsIgnoreCase("circle")) { shape = new CircleShape(); } else if (type.equalsIgnoreCase("rect")) { shape = new RectShape(); } else if (type.equalsIgnoreCase("triangle")) { shape = new TriangleShape(); } return shape; } }
在这个工厂类中通过传入不同的type可以new不同的形状,返回结果为Shape 类型,这个就是简单工厂核心的地方了。
客户端使用
画圆形
Shape shape= ShapeFactory.getShape("circle");
shape.draw();
画正方形
Shape shape= ShapeFactory.getShape("rect");
shape.draw();
画三角形
Shape shape= ShapeFactory.getShape("triangle");
shape.draw();
只通过给ShapeFactory传入不同的参数就实现了各种形状的绘制。以上就是简单工厂方式。
2、工厂方法模式
工厂方法模式是简单工厂的仅一步深化, 在工厂方法模式中,我们不再提供一个统一的工厂类来创建所有的对象,而是针对不同的对象提供不同的工厂。也就是说每个对象都有一个与之对应的工厂。
定义:定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。
实例:现在需要设计一个这样的图片加载类,它具有多个图片加载器,用来加载jpg,png,gif格式的图片,每个加载器都有一个read()方法,用于读取图片。下面我们完成这个图片加载类。
首先完成图片加载器的设计,编写一个加载器的公共接口。
public interface Reader { void read(); }
Reader 里面只有一个read()方法,然后完成各个图片加载器的代码。
Jpg图片加载器
public class JpgReader implements Reader { @Override public void read() { System.out.print("read jpg"); } }
Png图片加载器
public class PngReader implements Reader { @Override public void read() { System.out.print("read png"); } }
Gif图片加载器
public class GifReader implements Reader { @Override public void read() { System.out.print("read gif"); } }
现在我们按照定义所说定义一个抽象的工厂接口ReaderFactory
public interface ReaderFactory { Reader getReader(); }
里面有一个getReader()方法返回我们的Reader 类,接下来我们把上面定义好的每个图片加载器都提供一个工厂类,这些工厂类实现了ReaderFactory 。
Jpg加载器工厂
public class JpgReaderFactory implements ReaderFactory { @Override public Reader getReader() { return new JpgReader(); } }
Png加载器工厂
public class PngReaderFactory implements ReaderFactory { @Override public Reader getReader() { return new PngReader(); } }
Gif加载器工厂
public class GifReaderFactory implements ReaderFactory { @Override public Reader getReader() { return new GifReader(); } }
在每个工厂类中我们都通过复写的getReader()方法返回各自的图片加载器对象。
客户端使用:
读取Jpg
ReaderFactory factory=new JpgReaderFactory(); Reader reader=factory.getReader(); reader.read();
读取Png
ReaderFactory factory=new PngReaderFactory(); Reader reader=factory.getReader(); reader.read();
读取Gif
ReaderFactory factory=new GifReaderFactory(); Reader reader=factory.getReader(); reader.read();
可以看到上面三段代码,分别读取了不同格式的图片,不同之处在于针对不同的图片格式声明了不同的工厂,进而创建了相应的图片加载器。
和简单工厂对比一下,最根本的区别在于,简单工厂只有一个统一的工厂类,而工厂方法是针对每个要创建的对象都会提供一个工厂类,这些工厂类都实现了一个工厂基类(本例中的ReaderFactory )。下面总结一下工厂方法的适用场景。
适用场景:
(1)客户端不需要知道它所创建的对象的类。例子中我们不知道每个图片加载器具体叫什么名,只知道创建它的工厂名就完成了床架过程。
(2)客户端可以通过子类来指定创建对应的对象。
以上场景使用于采用工厂方法模式。

浙公网安备 33010602011771号