设计模式之工厂模式(Factory Pattern)
工厂模式在我们平时工作中还是非常常用的一种模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
-
工厂模式的定义
Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses。定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。 -
工厂模式通用类图
对上面的类图简单的说明:- 工厂接口IFactory用来生产定义产品对象。
- 产品接口IProduct用来定义产品对象的共性。
- 具体的产品类由具体工厂实现类Factory来创建的。
-
工厂模式通用代码
public interface IFactory {
IProduct createProduct();
}
public class Factory implements IFactory {
@Override
public IProduct createProduct() {
return new Product();
}
}
public interface IProduct {
void productMethod();
}
public class Product implements IProduct{
@Override
public void productMethod() {
System.out.println("I'm a product");
}
}
测试类:
public class Client {
public static void main(String[] args) {
IFactory f = new Factory();
IProduct p = f.createProduct();
p.productMethod();
}
}
-
通过工厂模式通用类图可以看到,工厂模式有四个要素:
- 工厂接口。工厂接口是工厂方法模式的核心,与调用者直接交互用来提*品。
- 工厂实现。在编程中,工厂实现决定如何实例化产品,是实现扩展的途径,需要有多少种产品,就需要有多少个具体的工厂实现。
- 产品接口。产品接口的主要目的是定义产品的规范。
- 产品实现。实现产品接口的具体类,决定了产品在客户端中的具体行为。
-
工厂模式实例
- 实例类图
- 实例代码
- 实例类图
public interface IShape {
void draw();
}
public class Circle implements IShape{
@Override
public void draw() {
System.out.println("This's Circle");
}
}
public class Square implements IShape{
@Override
public void draw() {
System.out.println("This's Square");
}
}
public class Rectangle implements IShape{
@Override
public void draw() {
System.out.println("This's Rectangle");
}
}
public interface ShapeFactory {
IShape getShape(String shape);
}
public class Factory implements ShapeFactory {
@Override
public IShape getShape(String shape) {
if (shape.equals("Circle")) {
return new Circle();
}
if (shape.equals("Square")) {
return new Square();
}
if(shape.equals("Rectangle")){
return new Rectangle();
}
return null;
}
}
public class Client {
public static void main(String[] args) {
ShapeFactory a = new Factory();
IShape b = a.getShape("Rectangle");
b.draw();
}
}
- 工厂模式带来的好处
- 良好的封装性,代码结构清晰,降低模块间的耦合度。比如一个调用者需要创建一个具体的产品对象,只需要知道这个产品的类名就可以了。
- 可扩展性很好。
- 符合迪米特法则和依赖倒置原则。
参考书籍:设计模式之禅
,Head First设计模式
实例代码放在这里。