ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## 工程方法模式 **定义**:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。 **我的理解**:工厂方法模式不是通过new关键字来创建对象的,而是通过工厂接口提供的方法来创建其他对象。 工厂设计模式,在开发过程中很常见,下面使用一个例子来引入普遍的工厂设计模式。 一个加工厂商加工不同的产品。 Product类,抽象类,表示不同的产品。 FoodProduct类,继承Product类,并实现其抽象方法。 FruitProduct类,继承Product类,并实现其抽象方法。 Creator类,是一个抽象工厂类,提供加工的方法。 NumberOneCreator类,表示一号工厂,实现其Creator类,用于加工不同的产品类。 ![](https://box.kancloud.cn/2016-06-06_575534080b02c.jpg) ~~~ public class FactoryTest { public static void main(String[] args) { //通过创建子类对象,将接口实例化。 Creator cFactory = new NumberOneCreator(); //通过子类的方法,创建一个需要的对象。 FoodProduct food = cFactory.createProduce(FoodProduct.class); food.mothod1(); food.mothod2(); } } //定义一个抽象的产品方法。 abstract class Product{ public void mothod1(){ System.out.println("方法一,加工的都是使用的产品..."); } public abstract void mothod2(); } class FruitProduct extends Product{ @Override public void mothod2() { System.out.println("方法二,生产出来了果汁...."); } } class FoodProduct extends Product{ @Override public void mothod2() { System.out.println("方法二,生产出来了零食...."); } } abstract class Creator{ public abstract <T extends Product> T createProduce(Class<T> t); } class NumberOneCreator extends Creator{ /** * 传入的参数,是Product类的子类。 */ @Override public <T extends Product> T createProduce(Class<T> t) { Product p = null; try { //Class类创建一个 工厂类实例 p = (Product) Class.forName(t.getName()).newInstance(); } catch (Exception e) { e.printStackTrace(); } return (T) p; } } ~~~ 工厂模式的优点: 1、具有良好的封装性,代码结构清晰。降低模块间的耦合性 2、工厂方法模式的扩展性非常优秀。 3、屏蔽产品类,产品类对外提供的是一个接口,只要接口不改变系统中的上层模块就不会发生改变。 ## 工厂模式的扩展: **1、缩小为简单的工厂模式(静态工厂模式)**    一个模块仅需要一个工厂类,没有必要把它产生出来,使用静态的方法就可以了。    ---该模式称为简单工厂模式(又称静态工厂模式)。调用者使用十分方便,开发中也经常用到,但是扩展不好。    UML类图 ![](https://box.kancloud.cn/2016-06-06_5755340824dda.jpg) ~~~ public class NvWatest { public static void main(String[] args) { YellowMan yellowMan = HumanFactory.CreatHuman(YellowMan.class); yellowMan.skin(); yellowMan.talk(); } } interface Human{ //人类的语言 void talk(); //人类的肤色 void skin(); } class BlackMan implements Human{ @Override public void talk() { System.out.println("我是黑种人,我说的是非洲语..."); } @Override public void skin() { System.out.println("我是黑种人,我的皮肤是黑色的..."); } } class WhiteMan implements Human{ @Override public void talk() { System.out.println("我是白种人,我说的是英语..."); } @Override public void skin() { System.out.println("我是白种人,我的皮肤是白色的..."); } } class YellowMan implements Human{ @Override public void talk() { System.out.println("我是黄种人,我说的是汉语..."); } @Override public void skin() { System.out.println("我是黄种人,我的皮肤是黄色的..."); } } class HumanFactory{ public static <T extends Human> T CreatHuman(Class<T> c){ Human man = null; try { man = (Human) Class.forName(c.getName()).newInstance(); } catch (Exception e) { e.printStackTrace(); } return (T) man; } } ~~~ **2、升级为多个设计模式** 将工厂类划分为YellowFactory,BlackFactory,WhiteFactory三类,都继承自抽象工厂。 这三中工厂分成实现创造不同的人类。 UML图 ![](https://box.kancloud.cn/2016-06-06_575534083a620.jpg) ~~~ public class NvWatest { public static void main(String[] args) { YellowMan yellowMan = (YellowMan) new YellowHumanFactory().CreatHuman(); yellowMan.skin(); yellowMan.talk(); } } interface Human{ //人类的语言 void talk(); //人类的肤色 void skin(); } class BlackMan implements Human{ @Override public void talk() { System.out.println("我是黑种人,我说的是非洲语..."); } @Override public void skin() { System.out.println("我是黑种人,我的皮肤是黑色的..."); } } class WhiteMan implements Human{ @Override public void talk() { System.out.println("我是白种人,我说的是英语..."); } @Override public void skin() { System.out.println("我是白种人,我的皮肤是白色的..."); } } class YellowMan implements Human{ @Override public void talk() { System.out.println("我是黄种人,我说的是汉语..."); } @Override public void skin() { System.out.println("我是黄种人,我的皮肤是黄色的..."); } } abstract class AbstractHumanFactory{ public abstract Human CreatHuman(); } class BlackHumanFactory extends AbstractHumanFactory{ @Override public Human CreatHuman() { // TODO Auto-generated method stub return new BlackMan(); } } class YellowHumanFactory extends AbstractHumanFactory{ @Override public Human CreatHuman() { // TODO Auto-generated method stub return new YellowMan(); } } class WhiteHumanFactory extends AbstractHumanFactory{ @Override public Human CreatHuman() { // TODO Auto-generated method stub return new WhiteMan(); } } ~~~ 以下两种暂时不懂得利用的价值,但是还是先了解一下为好 **3、替代单例模式** 创建一个单例工厂,来创建需要创建的类。并保证只有一个实例对象。 ![](https://box.kancloud.cn/2016-06-06_57553408527fb.jpg) ~~~ public class SingletonTest { public static void main(String[] args) { Singleton s = new SingtonFactory().getSingle(); s.mothod1(); } } class SingtonFactory{ private static Singleton single; static{ try { Class c = Class.forName(Singleton.class.getName()); //获得无参构造 Constructor<Singleton> constractor = c.getDeclaredConstructor(); //设置无参构造是可访问的 constractor.setAccessible(true); //产生一个实例对象 single = constractor.newInstance(); } catch (Exception e) { System.out.println("创建实例失败..."); } } public Singleton getSingle(){ return single; } } class Singleton{ //不让外界调用者创建实例 private Singleton(){ } public void mothod1(){ System.out.println("sington的一个方法...."); } } ~~~ **4、延迟初始化** 一个对象被消费完毕后,并不立刻释放,工厂类保持其初始状态,等待再次被使用。 ![](https://box.kancloud.cn/2016-06-06_575534086b9ff.jpg) ~~~ public class FactoryTest { public static void main(String[] args) { for(int i=0;i<5;i++){ Product p = new Creator().createProduce("food"); p.mothod1(); p.mothod2(); System.out.println("------------------------------"); } } } //定义一个抽象的产品方法。 abstract class Product{ public void mothod1(){ System.out.println("方法一,加工的都是使用的产品..."); } public abstract void mothod2(); } class FruitProduct extends Product{ @Override public void mothod2() { System.out.println("方法二,生产出来了果汁...."); } } class FoodProduct extends Product{ @Override public void mothod2() { System.out.println("方法二,生产出来了零食...."); } } class Creator { private static Map<String,Product> map = new HashMap<String, Product>(); public static synchronized Product createProduce(String type) { Product p = null; //首先判断map集合中是否存在该对象 if(map.containsKey(type)){ System.out.println("-----------存在该对象-------------"); p = map.get(type); }else{ //如果不存在,就根据类型来创建不同的实例 if(type.equals("food")){ p = new FoodProduct(); }else{ p = new FruitProduct(); } } map.put(type, p); return p; } } ~~~