工厂概念
在现实生活中有各种各样的制造生产类型的公司,比如有生产罐头的公司,有制造电脑的公司,有生产汽车的公司。所有类似的这些公司都可以称之为工厂,各种各样的工厂。这些工厂的作用往大了说只有一个那就是制造产品。
同样在软件开发领域。也有各种各样的工厂。所有工厂都有一个共同的功能那就是创建对象(比如生产汽车 电脑 罐头等)。我们可以把工厂的功能定义成一个只有一个创建对象的方法的接口。比如:
public interface Factory {
Object create();
}
复制代码
这样就相当于将工厂的功能做了一次抽象,然后生产具体产品的工厂可以实现 Factory 工厂接口。
工厂分类
这个文章将工厂模式分为两种;可能和很多网上和书中的教程划分的不一样,但是这并不影响对于工厂模式的理解
普通的工厂模式
使用工厂创建的对象都是属于同一个继承体系的实例。比如可以返回某一个接口引用或者返回某个父类的引用。不同的工厂实现类创建具体的接口实现类或者子类。下面将会展示很多代码
泛型工厂模式
使用工厂创建泛型对象。这些对象可以属于同一个继承体系,也可以毫无瓜葛。
要想讲明白一个知识点仅靠一篇文章肯定不行,所以为了弄明白什么是工厂模式?怎么写工厂模式?以及在真实代码中的工厂模式是如何运用的?我会分多篇来写
普通工厂模式示例演示:首先定义两个接口
interface Product { //工厂要创建的对象都实现于此接口
void method();
//当然还可以定义很多方法
}
interface ProductFactory {
Product create();
}
复制代码
ProductFactory
就是我们的工厂接口,create 方法返回 Product 接口引用
接下来要定义具体的Product
的实现类以及用于创建该实现类的具体的工厂类
首先定义第一个 2 件套
class Implementation1 implements Product {
Implementation1() {} //包访问权限
@Override public void method() { print("Implementation1method"); }
}
class Implementation1Factory implements ProductFactory {
@Override public Product create() {return new Implementation1();}
}
复制代码
再来一个 2 件套
class Implementation2 implements Product {
Implementation2() {} //包访问权限
public void method() {
print("Implementation2method1");
}
}
class Implementation2Factory implements ProductFactory {
@Override public Product create() {return new Implementation2();}
}
复制代码
一个具体的产品类配上一个创建这个类的具体的工厂类
然后看一下如何使用工厂
public class Factories {
public static void consumer(ProductFactory factory) {
Product p = factory.create();
p.method();
}
public static void main(String[] args) {
consumer(new Implementation1Factory());
consumer(new Implementation2Factory());
}
}
复制代码
consumer()
方法使用工厂接口引用作为参数,通过此接口动态的调用create()
方法,从而在consumer()
方法中可以将对象的创建和使用完全接耦。当我们将不同的工厂接口传入consumer()
方法中时,在方法内部会透明的将某个实现替换为另一个实现。那如果不使用工厂方法会有什么问题?我们可以把使用 Prodect 对象的代码片段当作一个通用性的方法,在这里就是 consumer 方法,如果没有工厂接口,我们必须要自己创建具体的 Product 对象,而这样我们的代码势必会和具体对象的创建紧耦合。但是我们是想要创建一个更通用性的与具体实现无关的框架。
还有一个比较贴近于真实世界的例子:一个对弈游戏系统,例如在相同的棋盘上下不同的棋;
同样还是先定义两个接口Game
和GameFactory
,和上面的Product
和ProductFactory
相对应。
interface Game { boolean move(); }
interface GameFactory { Game getGame(); }
复制代码
然后需要定义一个实现了Game
接口的跳棋类,对应的再定义一个创建跳棋对象的具体工厂类,代码如下:
//代表跳棋游戏
class Checkers implements Game {
private int moves = 0;
private static final int MOVES = 5;
@Override
public boolean move() {
System.out.println("Checkers move " + moves);
return ++moves != MOVES;
}
}
class CheckerFactory implements GameFactory {
@Override
public Game getGame() {
return new Checkers();
}
}
class Chess implements Game {
private int moves = 0;
private static final int MOVES = 4;
@Override
public boolean move() {
System.out.println("Chess move " + moves);
return ++moves != MOVES;
}
}
class ChessFactory implements GameFactory {
@Override
public Game getGame() {
return new Chess();
}
}
复制代码
接着再来看一下工厂方法的简单使用场景:
public class Games {
public static void playGames(GameFactory factory) {
Game game = factory.getGame();
while (game.move())
;
}
public static void main(String[] args) {
playGames(new CheckerFactory());
playGames(new CheckerFactory());
}
}
复制代码
依然是playGames()
方法以工厂接口作为参数,在方法内部多态调用getGame()
方法,从而动态创建具体的 Game 实现类。将创建 Game 的具体操作分离出去达到解耦合效果。
通过上面的两个例子可以看出简单的的工厂设计模式的通用规则:即一个具体的工厂生产一个具体的对象,还有一个使用工厂接口引用去创建对象的地方。而这个引用可以被动态的赋值为不同的工厂实现类从而产生不同的对象
这篇文章只是为了展示工厂模式最基本的概念所以使用了最无实际意义的代码。其实看完这些代码可能对工厂模式还是一知半解。那么在下一篇中我们看看真实世界中的工厂到底是如何运用的
评论 (1 条评论)