创建型模式5之1-FactoryMethod工厂方法模式例子理解

来源:互联网 发布:淘宝联盟如何赚钱 编辑:程序博客网 时间:2024/05/22 13:39

例子一

package com.test.factorymodel;/** *  工厂方法:一抽象产品类派生出多个具体产品类;一抽象工厂类派生出多个具体工厂类;每个具体工厂类只能创建一个具体产品类的实例。    即定义一个创建对象的接口(即抽象工厂类),让其子类(具体工厂类)决定实例化哪一个类(具体产品类)。“一对一”的关系。    在以下情况下,适用于工厂方法模式:(1) 当一个类不知道它所必须创建的对象的类的时候。(2) 当一个类希望由它的子类来指定它所创建的对象的时候。(3) 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。 * @author Administrator * */public class FactoryMethod {    // 抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。    public static abstract class Phone {        public Phone() {            // TODO Auto-generated constructor stub        }    }    // 具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。    public static class iPhone extends Phone {        public iPhone() {            // TODO Auto-generated constructor stub            System.out.println("iPhone");        }    }    // 具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。    public static class AndroidPhone extends Phone {        public AndroidPhone() {            // TODO Auto-generated constructor stub            System.out.println("AndroidPhone");        }    }    // 抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。    public interface IFactory {        Phone createPhone();    }    // 具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。    public static class iPhoneFactory implements IFactory {        @Override        public Phone createPhone() {            // TODO Auto-generated method stub            return new iPhone();        }    }    // 具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。    public static class AndroidPhoneFactory implements IFactory {        @Override        public Phone createPhone() {            // TODO Auto-generated method stub            return new AndroidPhone();        }    }    public static class FactoryMethod_Customer {        public static void main(String[] args) {            iPhoneFactory factoryiPhone = new iPhoneFactory();            Phone iPhone = factoryiPhone.createPhone();            AndroidPhoneFactory factoryAndroidPhone = new AndroidPhoneFactory();            Phone androidPhone = factoryAndroidPhone.createPhone();        }    }}

例子二
这里写图片描述

interface Human {    public void Talk();    public void Walk();}class Boy implements Human{    @Override    public void Talk() {        System.out.println("Boy is talking...");            }    @Override    public void Walk() {        System.out.println("Boy is walking...");    }}class Girl implements Human{    @Override    public void Talk() {        System.out.println("Girl is talking...");       }    @Override    public void Walk() {        System.out.println("Girl is walking...");    }}public class HumanFactory {    public static Human createHuman(String m){        Human p = null;        if(m == "boy"){            p = new Boy();        }else if(m == "girl"){            p = new Girl();        }        return p;    }}

工厂模式:
首先需要说一下工厂模式。工厂模式根据抽象程度的不同分为三种:简单工厂模式(也叫静态工厂模式)、本文所讲述的工厂方法模式、以及抽象工厂模式。工厂模式是编程中经常用到的一种模式。它的主要优点有:
可以使代码结构清晰,有效地封装变化。在编程中,产品类的实例化有时候是比较复杂和多变的,通过工厂模式,将产品的实例化封装起来,使得调用者根本无需关心产品的实例化过程,只需依赖工厂即可得到自己想要的产品。
对调用者屏蔽具体的产品类。如果使用工厂模式,调用者只关心产品的接口就可以了,至于具体的实现,调用者根本无需关心。即使变更了具体的实现,对调用者来说没有任何影响。
降低耦合度。产品类的实例化通常来说是很复杂的,它需要依赖很多的类,而这些类对于调用者来说根本无需知道,如果使用了工厂方法,我们需要做的仅仅是实例化好产品类,然后交给调用者使用。对调用者来说,产品所依赖的类都是透明的。

工厂方法模式:
通过工厂方法模式的类图可以看到,工厂方法模式有四个要素:
工厂接口。工厂接口是工厂方法模式的核心,与调用者直接交互用来提供产品。在实际编程中,有时候也会使用一个抽象类来作为与调用者交互的接口,其本质上是一样的。
工厂实现。在编程中,工厂实现决定如何实例化产品,是实现扩展的途径,需要有多少种产品,就需要有多少个具体的工厂实现。
产品接口。产品接口的主要目的是定义产品的规范,所有的产品实现都必须遵循产品接口定义的规范。产品接口是调用者最为关心的,产品接口定义的优劣直接决定了调用者代码的稳定性。同样,产品接口也可以用抽象类来代替,但要注意最好不要违反里氏替换原则。
产品实现。实现产品接口的具体类,决定了产品在客户端中的具体行为。
前文提到的简单工厂模式跟工厂方法模式极为相似,区别是:简单工厂只有三个要素,他没有工厂接口,并且得到产品的方法一般是静态的。因为没有工厂接口,所以在工厂实现的扩展性方面稍弱,可以算所工厂方法模式的简化版,关于简单工厂模式,在此一笔带过。

适用场景:
不管是简单工厂模式,工厂方法模式还是抽象工厂模式,他们具有类似的特性,所以他们的适用场景也是类似的。
首先,作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过new就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。
其次,工厂模式是一种典型的解耦模式,迪米特法则在工厂模式中表现的尤为明显。假如调用者自己组装产品需要增加依赖关系时,可以考虑使用工厂模式。将会大大降低对象之间的耦合度。
再次,由于工厂模式是依靠抽象架构的,它把实例化产品的任务交由实现类完成,扩展性比较好。也就是说,当需要系统有比较好的扩展性时,可以考虑工厂模式,不同的产品用不同的实现工厂来组装。

===================================

补充例子:
1.HairInterface

    package com.test.factorymodel.two4factorymethod;public interface HairInterface {    public void colorHair();}

2.RedHair

package com.test.factorymodel.two4factorymethod;public class RedHair implements HairInterface{    @Override    public void colorHair() {        // TODO Auto-generated method stub        System.out.println("染成红色头发");    }}

3.YellowHair

package com.test.factorymodel.two4factorymethod;public class YellowHair implements HairInterface {    @Override    public void colorHair() {        // TODO Auto-generated method stub        System.out.println("染成黄色头发");    }}

4.HairFactory

package com.test.factorymodel.two4factorymethod;import java.util.Map;public class HairFactory {    /**     * 根据类型来创建对象     *      * @param key     * @return     */    public HairInterface getHair(String key) {        if ("red".equals(key)) {            return new RedHair();        } else if ("yellow".equals(key)) {            return new YellowHair();        }        return null;    }    /**     * 根据类的名称来生产对象     * @param className     * @return     */    public HairInterface getHairByClass(String className){        try {            HairInterface hair = (HairInterface) Class.forName(className).newInstance();            return hair;        } catch (InstantiationException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IllegalAccessException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (ClassNotFoundException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        return null;    }    /**     * 根据类的名称来生产对象     * @param className     * @return     */    public HairInterface getHairByClassKey(String key){        try {            Map<String, String> map = new PropertiesReader().getProperties();            HairInterface hair = (HairInterface) Class.forName(map.get(key)).newInstance();            return hair;        } catch (InstantiationException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IllegalAccessException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (ClassNotFoundException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        return null;    }}

6.PropertiesReader

package com.test.factorymodel.two4factorymethod;import java.io.InputStream;import java.util.Enumeration;import java.util.HashMap;import java.util.Map;import java.util.Properties;/** * properties文件的读取工具 * @author Administrator * */public class PropertiesReader {    public Map<String, String> getProperties() {        Properties props = new Properties();        Map<String, String> map = new HashMap<String, String>();        try {            InputStream in = getClass().getResourceAsStream("type.properties");            props.load(in);            Enumeration en = props.propertyNames();            while (en.hasMoreElements()) {                String key = (String) en.nextElement();                String property = props.getProperty(key);                map.put(key, property);//              System.out.println(key + "  " + property);            }        } catch (Exception e) {            e.printStackTrace();        }        return map;    }}

7.type.properties

red=com.test.factorymodel.two4factorymethod.RedHairyellow=com.test.factorymodel.two4factorymethod.YellowHair

8.Test

package com.test.factorymodel.two4factorymethod;public class Test {    public static void main(String[] args) {        //原始的        HairInterface red = new RedHair();        red.colorHair();        //工厂        HairFactory factory = new HairFactory();        HairInterface yellow = factory.getHair("yellow");        yellow.colorHair();        HairInterface red2 =        factory.getHairByClass("com.test.factorymodel.two4factorymethod.RedHair");        red2.colorHair();        HairInterface hair = factory.getHairByClassKey("yellow");        hair.colorHair();    }}

9.结果

染成红色头发染成黄色头发染成红色头发染成黄色头发
0 0
原创粉丝点击