前言 本文讲讲工厂模式。
正文 概念 工厂模式是Java中常用的一种设计模式,它属于创建型模式的一种,又称为工厂方法模式,这种模式提供了创建对象的一种方法,对客户端隐藏生成对象的逻辑,使用一个接口来指向新的对象。 常见的实例有:
工厂提供多种产品,你可以直接购买,无需关心如何制作。
日志管理,可以使用多种方式记录,并且可以记录到本地,远程等等。
数据库访问,不知道系统最后使用哪种数据库时,封装可用的数据库。
当对象较为复杂时,使用工厂模式较为适合,如果对象十分简单,那直接使用new生成就可以了。
实现 下面我们用一个例子来实现工厂模式。 例如游戏公司要制作几个新的游戏。 我们将创建一个游戏Game接口,以及实现它的实体类,然后创建工厂去制作游戏。 我们先定义Game接口
1 2 3 public interface Game { void test () ; }
接着定义几个游戏A,B,C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class GameA implements Game { @Override public void test () { System.out.println("this is Game A" ); } } public class GameB implements Game { @Override public void test () { System.out.println("this is Game B" ); } } public class GameC implements Game { @Override public void test () { System.out.println("this is Game C" ); } }
接着创建工厂,根据名称生成实体类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class GameFactory { public Game getGame (String name) { if (name == null ){ return null ; } if (name.equalsIgnoreCase("GameA" )){ return new GameA(); }else if (name.equalsIgnoreCase("GameB" )){ return new GameB(); }else if (name.equalsIgnoreCase("GameC" )){ return new GameC(); } return null ; } }
接着编写客户端进行调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class Client { public static void main (String[] args) { GameFactory gameFactory = new GameFactory(); Game game1 = gameFactory.getGame("GameA" ); game1.test(); Game game2 = gameFactory.getGame("GameB" ); game2.test(); Game game3 = gameFactory.getGame("GameC" ); game3.test(); } }
后续思考 以上我们就实现了一个简单的工程模式示例,当然从上述工厂的代码来看,肯定是不够优雅的,毕竟我们需要写很多的if else,或者case语句。 那我自己想到的点是,通过一个枚举类或者常量,提供所有可以创建对象的关键字,然后通过关键字所对应的值,来进行反射创建操作。 例如创建一个GameType类
1 2 3 4 5 public class GameType { static final String GameA = GameA.class.getName(); static final String GameB = GameB.class.getName(); static final String GameC = GameC.class.getName(); }
修改GameFactory
1 2 3 4 5 6 7 8 9 public Game getGame2 (String type) { try { return (Game) Class.forName(type).newInstance(); }catch (Exception e){ e.printStackTrace(); } return null ; }
对应client
1 2 3 Game game = gameFactory.getGame2(GameType.GameA); game.test();
算是少些了一下冗余吧,当然也可以使用枚举类,这里就不再多写了。优化一下就少了许多if else。
优缺点 工厂模式的优点在于客户端只需知道名称就可以创建一个对象,并且拓展性较好,而且屏蔽了类的具体实现。 而缺点就是在增加一个产品之后,就需要添加具体类与修改工厂,增加系统的复杂性。
总结 本文总结了简单工厂模式,当然,从本文的例子看并不需要工厂模式去创建对象,但是当对象较为复杂时,例如对象依赖于其他对象,那在客户端中就没必要自己实现对象,而是交给工厂实现。而当客户端不知道需要创建对象的类时,也可以使用工厂模式来设计系统。 之后会讲讲工厂模式的进阶,抽象工厂模式,算是一个比较难的模式。