对应慕课视频的连接:https://www.imooc.com/video/5316

1,工厂模式的应用场景

有一组类似的对象需要被创建

在编码时不能预见需要被创建哪种类的实例

在系统需要考虑扩展性的情况下,不应依赖产品类实例如何创建,组合和表达的细节

2,项目中的现状:

在软件系统中经常面临着“对象”的创建工作,由于需求的变化,这个对象可能随之发生改变,但它却拥有比较稳定的接口。

为此我们需要提供一种风专辑之来隔离这个易变对象的变化,从而保持系统中其他依赖对该对象的对象不随着需求变化而改变

 

 

比如说,客户端要求生产苹果,creater就生产苹果,Uproduct就代表水果,他下面的Product1,Product2,Product3就可以表苹果,香蕉,橘子等具体的水果

在抽象工厂中呢,用户发出请求,factory生产水果,CreateFactory1,CreateFactory2他两个都可生产两种类型的水果,但是生产的具体产品又各不相同,CreateFactory1,CreateFactory2为两个系列。

 一、代码部分(工厂模式实现)

(1)是定义生产头发的接口类

package com.songyan.factory;
/**
 * 生产头发
 * @author Administrator
 *
 */
public interface Hair {
    public void draw();
}

(2)定义生产发型的实现类:生产左偏分发型的类,生产右偏分发型的类

package com.songyan.factory;

public class LeftHair implements Hair{

    @Override
    public void draw() {
        System.out.println("left hair");
    }
    
}
package com.songyan.factory;

public class RightHair implements Hair{

    @Override
    public void draw() {
        System.out.println("right hair");
    }

}

(3)编写测试类,生产左偏分发型

package com.songyan.factory;

public class Test {
    public static void test1()
    {
        Hair hair=new LeftHair();
        hair.draw();
        
    }

    public static void main(String[] args) {
    
        test1();
        
    }
}

这种方法生产发型是在客户端生产,不安全------>在工厂中生产发型

(4)定义生产发型的工厂类

package com.songyan.factory;

import java.util.HashMap;
import java.util.Map;

public class HairFactory {
    public static Hair getHair(String key)
    {
        Hair hair=null;
        if("left".equals(key))
        {
            hair=new LeftHair();
        }
        else if("right".equals(key))
        {
            hair=new RightHair();
        }
        return hair;
    }
    
    
}

(5)编写对应的测试类

package com.songyan.factory;

public class Test {
    public static void test1()
    {
        Hair hair=new LeftHair();
        hair.draw();
        
    }
    public static void test2()
    {
        HairFactory factory=new HairFactory();
        Hair hair=factory.getHair("left");
        hair.draw();
    }public static void main(String[] args) {
    
        //test1();
        test2();
    }
}

这种方式,当添加新的发型时,需要在factory中添加新的else if判断(不合理)---->运用反射的技术,通过类名,动态的创建对象

反射的知识点:http://www.cnblogs.com/excellencesy/p/8868567.html

(6)通过反射创建对象

package com.songyan.factory;

import java.util.HashMap;
import java.util.Map;

public class HairFactory {

    public static Hair getHairByClass(String ClassName)
    {
        Hair hair=null;
        try {
            hair=(Hair) Class.forName(ClassName).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        
        return hair;
    }
    
}

通过传入累的全名,创建对应的对象

(7)对应的测试方法test3()

package com.songyan.factory;

public class Test {
    public static void test1()
    {
        Hair hair=new LeftHair();
        hair.draw();
        
    }
    public static void test2()
    {
        HairFactory factory=new HairFactory();
        Hair hair=factory.getHair("left");
        hair.draw();
    }
    public static void test3()
    {
        HairFactory factory=new HairFactory();
        Hair hair=factory.getHairByClass("com.songyan.factory.LeftHair");
        hair.draw();
    }

    public static void main(String[] args) {
    
        //test1();
        //test2();
        test3();

    }
}

这种方式需要输入复杂的类全名(不合理)----->配置简单的关键字

(8)编写配置文档type.properties

left=com.songyan.factory.LeftHair
right=com.songyan.factory.RightHair

(9)编写配置文档的读取类及方法

package com.songyan.factory;

import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;

public class PropertiesReader {
    public Map<String,String> getProperties()
    {
        //定义储存properties的map集合
        Map<String ,String> map= new HashMap<String,String>();
        //定义properties对象,操作Properties文件
        Properties pro=new Properties();
        //输入流以行的形式输入
        InputStream in=getClass().getResourceAsStream("type.properties") ;
        try {
            pro.load(in);
            
            Enumeration enu=pro.propertyNames();
            while(enu.hasMoreElements())
            {
                //
                String key =(String)enu.nextElement();
                String value=pro.getProperty(key);
                map.put(key,value);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        return map;
    }
}

(10)编写相应的工厂方法

package com.songyan.factory;

import java.util.HashMap;
import java.util.Map;

public class HairFactory {
    
    public static Hair getHairByKey(String key)
    {
        Hair hair=null;
        Map<String,String> map=new HashMap<String,String>();
        PropertiesReader reader=new PropertiesReader();
        map=reader.getProperties();
        System.out.println(map);
        String className=map.get(key);
        try {
            hair=(Hair) Class.forName(className).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return hair;
    }
}

(11)编写对应的测试test4()

package com.songyan.factory;

public class Test {
    public static void test4()
    {
        HairFactory factory= new HairFactory();
        Hair hair=factory.getHairByKey("left");
        hair.draw();
    }
    public static void main(String[] args) {

        test4();
    }
}

 二、工厂模式的应用(抽象工厂)

抽象工厂的代码实现

(1)定义生产男孩子的接口、女孩子接口

 

package com.songyan.factory;
/**
 * 男孩接口
 * @author Administrator
 *
 */
public interface Boy {
    public void drawMan();
}

 

 

package com.songyan.factory;
/**
 *女孩接口
 * @author Administrator
 *
 */
public interface Girl {
    public  void drawWomen();
}

 

(2)定义新年男孩,圣诞男孩 继承男孩,

定义新年女孩,圣诞女孩 继承女孩,

package com.songyan.factory;
/**
 * 新年男孩
 * @author Administrator
 * 
 */
public class HNBoy implements Boy{

    @Override
    public void drawMan() {
        System.out.println("新年男孩");
        
    }
    
}
package com.songyan.factory;
/**
 * 圣诞男孩
 * @author Administrator
 *
 */
public class MCBoy implements Boy{

    @Override
    public void drawMan() {
        System.out.println("圣诞男孩");
    }

}

 

package com.songyan.factory;
/**
 * 新年女孩
 * @author Administrator
 *
 */
public class HNGirl implements Girl{

    @Override
    public void drawWomen() {
        System.out.println("新年女孩");
    }

}
package com.songyan.factory;
/**
 * 圣诞女孩
 * @author Administrator
 *
 */
public class MCGirl implements Girl{

    @Override
    public void drawWomen() {
        System.out.println("圣诞女孩");
        
    }

}

(3)定义生产男孩女孩的工厂接口

package com.songyan.factory;
/**
 * 生产男孩女孩的工厂接口
 * @author Administrator
 *
 */
public interface PersonFactory {
    //生产男孩子
    public Boy getBoy();
    //生产女孩子
    public Girl getGirl();
}

(4)生产

新年

类型的男孩子,女孩子

package com.songyan.factory;
/**
 * 生产新年类型的男孩子,女孩子
 * @author Administrator
 *
 */
public class HNFactory implements PersonFactory {

    @Override
    public Boy getBoy() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Girl getGirl() {
        // TODO Auto-generated method stub
        return null;
    }

}

(5)生产圣诞类型的男孩子,女孩子

package com.songyan.factory;
/**
 * 生产圣诞类型的男孩子,女孩子
 * @author Administrator
 *
 */
public class MCFactory implements PersonFactory{

    //
    @Override
    public Boy getBoy() {
        return null;
    }

    @Override
    public Girl getGirl() {
        return null;
    }

}

(6)编写测试类

package com.songyan.factory;

public class Test2 {
public static void main(String[] args) {
    //绘制圣诞女孩
    PersonFactory factory=new MCFactory();
    Girl girl=factory.getGirl();
    girl.drawWomen();
    
}
}

 

抽象工厂的应用

(1)数据库的链接

(2)生产bean返回给客户端

    

 

 三、工厂模式总结

    

 

    

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted on 2018-04-16 16:06  song.yan  阅读(174)  评论(0编辑  收藏  举报