设计模式(1) ——- 简单工厂模式
- 这几天打算开始学习一下设计模式,所以写几篇博文来分享一下也用来督促自己哈
- 对于设计模式不同的高级语言有不同的表达,但总体或者说是思想都是差不多的,这里是基于Java的
- 初次学习难免有很多错误,希望可以和大家一起讨论
- 好了,废话少说开干
概述
简单工厂模式的组成
工厂类角色
本模式的核心,往往是一个具体的 Java静态 类。提供给客户(指使用你写的类库的人)来获得接口的实例。
抽象产别角色
往往是一个具体的 Java接口 类。这里的作用其实就是利用接口来定义所需实现的功能或称为所需要求。
具体产品角色
往往是一个具体的 Java 类。其实就是适应接口要求的具体实现。
简单工厂模式图示
简单工厂模式的本质
选择“实现”。注意简单工厂的重点在选择,实现已经做好了,就算实现再简单,也是有具体的实现类来实现,而不是在简单工厂里面来实现。
举例说明
案例说明
在金元攻势下,英超已经成为当今世界的第一足球联赛。另外在美国,NBA是世界第一篮球联赛。假设有个球员联盟负责登记和注册远动员,无论是足球远动员还是篮球远动员都必须在这里注册,才能被允许参加联赛。一家体育俱乐部(比如曼联、湖人)想要获得球员为自己的俱乐部效力,就必须通过这个“球员联盟”。
代码
接口类
package 简单工厂; public interface 球员 { void 跑(); void 跳(); }
工厂类
package 简单工厂; import java.io.InputStream; import java.util.Properties; public class 球员Factory { //方案一 利用参数区分不同类型球员 public static 球员 get球员1(int type){ 球员 sporter = null; if (type == 1) sporter = new 篮球球员(); else if (type == 2) sporter = new 足球球员(); return sporter; } //方案二 利用配置文件区分不同类型的球员 public static 球员 get球员2(){ Properties properties = new Properties(); try(InputStream in = 球员Factory.class.getResourceAsStream("FactoryTest.properties")){ properties.load(in); }catch (Exception e){ e.printStackTrace(); } 球员 sporter = null; try { sporter = (球员) Class.forName("简单工厂." + properties.getProperty("ImplClass")).newInstance(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } return sporter; } }
具体实现类
package 简单工厂; public class 篮球球员 implements 球员{ @Override public void 跑() { System.out.println("篮球球员跑!!!"); } @Override public void 跳() { System.out.println("篮球球员跳!!!"); } } package 简单工厂; public class 足球球员 implements 球员{ @Override public void 跑() { System.out.println("足球球员跑!!!"); } @Override public void 跳() { System.out.println("足球球员跳!!!"); } } package 简单工厂; public class PingPangSporter implements 球员{ @Override public void 跑() { System.out.println("乒乓球球员也会跑!!!"); } @Override public void 跳() { System.out.println("乒乓球球员更能跳!!!"); } }
方案二的配置文件内容 FactoryTest.properties
ImplClass=PingPangSporter
测试
package 简单工厂; public class 俱乐部 { private 球员 守门员; private 球员 前锋; private 球员 后卫; public void test(){ this.守门员 = 球员Factory.get球员1(2); this.前锋 = 球员Factory.get球员1(2); this.后卫 = 球员Factory.get球员2(); } public static void main(String[] args) throws ClassNotFoundException { 俱乐部 club = new 俱乐部(); club.test(); club.前锋.跑(); club.守门员.跳(); club.后卫.跳(); } }
说明:在 Factory 类中有两种方案,这两种方案是为了解决如何来创建不同的具体实现类的接口实例。说的有点绕 $_$ 如果没看懂就只保留方案一即可。
注意:对于配置文件,我在测试时发现只能使用 asc 编码。
总结
- 工厂模式的思想始于接口,这里把只是简单的把实现藏在了内部,而用户只需要选择实现。这样就实现了客户端和具体实现类的解耦。
- 其实简单工厂类还有个致命的缺点,这正是称它为简单的原因,至于是什么下次再写吧。累啦~~~