java设计模式一工厂模式

工厂模式

描述:
  • 定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
使用场景:
  • 消费者不关心它所要创建对象的类(产品类)的时候。
  • 消费者知道它所要创建对象的类(产品类),但不关心如何创建的时候···等等。
  • 应用场景举例:
    1、您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。
    2、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。
    3、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。
优点:
  • 一个调用者想创建一个对象,只要知道其名称就可以了。
  • 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
  • 屏蔽产品的具体实现,调用者只关心产品的接口。
缺点:
  • 每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。

一、简单工厂模式(静态工厂模式)

例子如下:

Animal类:

package com.bean;  
/** 
 * 动物类 
 * @author Lyon Yao 
 * 
 */  
public abstract class Animal {  

    private String name;  

    public Animal() {  
        super();  
        // TODO Auto-generated constructor stub  
    }  
    public Animal(String name) {  
        super();  
        this.name = name;  
    }  
    public abstract void eat();  
    public String getName() {  
        return name;  
    }  
    public void setName(String name) {  
        this.name = name;  
    }  

}  

猫类:

package com.bean;  

/** 
 * 猫类 
 * @author Lyon Yao 
 * 
 */  
public class Cat extends Animal {  

    public Cat() {  
        // TODO Auto-generated constructor stub  
    }  

    public Cat(String name) {  
        super(name);  
        // TODO Auto-generated constructor stub  
    }  

    @Override  
    public void eat() {  
        // TODO Auto-generated method stub  
        System.out.println("I like to eat fish!");  
    }  

}  

狗类:

/** 
 * 狗类 
 * @author Lyon Yao 
 * 
 */  
public class Dog extends Animal {  

    public Dog() {  
        // TODO Auto-generated constructor stub  
    }  

    public Dog(String name) {  
        super(name);  
        // TODO Auto-generated constructor stub  
    }  

    @Override  
    public void eat() {  
        // TODO Auto-generated method stub  
        System.out.println("I like to eat bone!");  
    }  

}  

静态工厂类:

package com.factory.sta;  

import java.lang.reflect.Constructor;  
import java.lang.reflect.InvocationTargetException;  

/** 
 * 静态工厂创建一个对象  静态工厂类产生的对象一般都有共同的特性,继承某一类,或者引用接口之类,在此 
 * 没有看似没有,但不可否认他们都是Object或者Object的一个子类 
 * @author Lyon Yao 
 * 
 */  
public class StaticFatory {  
    public static Object getInstance(String className){  
        Object instance=null;  
        try {  
            Class cls=Class.forName(className);  
            instance= cls.newInstance();  
        } catch (ClassNotFoundException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (InstantiationException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (IllegalAccessException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
        return instance;  

    }  
    public static Object getInstance(String className,Object ...agrs) {  
        Class cls=null;  
        try {  
            cls = Class.forName(className);  
        } catch (ClassNotFoundException e1) {  
            // TODO Auto-generated catch block  
            return null;  
        }  
        Constructor[] constructors = cls.getConstructors();  
        Object instance=null;  
        for(Constructor cons:constructors){  
            Class <?>[] clses=cons.getParameterTypes();  
            if(clses.length>0){  
                boolean isThisConstructor=true;  
                for(int i=0;i<clses.length;i++){  
                    Class c=clses[i];   
                    if(! c.isInstance(agrs[i]) ){  
                        isThisConstructor=false;  
                    }  
                }  
                if(isThisConstructor){  
                    try {  
                        instance=cons.newInstance(agrs);  
                        break;  
                    } catch (IllegalArgumentException e) {  
                        // TODO Auto-generated catch block  
                        e.printStackTrace();  
                    } catch (InvocationTargetException e) {  
                        // TODO Auto-generated catch block  
                        e.printStackTrace();  
                    } catch (InstantiationException e) {  
                        // TODO Auto-generated catch block  
                        e.printStackTrace();  
                    } catch (IllegalAccessException e) {  
                        // TODO Auto-generated catch block  
                        e.printStackTrace();  
                    }  
                }else{  
                    continue;  
                }  

            }  
        }  
        return instance;  
    }  
}  

二、工厂方法模式:

  • 其主要是对各个类型的东西分类生产,但分类生产的对象仍然是具有某一特性的。譬如说:前面的静态工厂类是一个综合造车工厂,不管是汽车还是火车都能生产,而工厂方法模式就是工厂具体分工,造汽车的工厂只造汽车,造火车的只造火车,不管造汽车还是火车但造出来的还是车。

  • 具体代码例子如下:(这里的例子和上面的例子是一起的,狗生好多小狗,猫生好多小猫的例子,如果不具体那么是母动物都能生的)

母动物接口:

package com.factory;  

import com.bean.Animal;  

/** 
 * 母亲接口 
 * @author Lyon 
 * 
 */  
public interface AnimalMother {  
    /** 
     * 生育动物 
     * @return 
     */  
    public  Animal giveBirth();  
}  

母狗类:

package com.factory.impl;  

import com.bean.Animal;  
import com.bean.Dog;  
import com.factory.AnimalMother;  

/** 
 * 狗母亲  生狗 
 * @author Lyon Yao 
 * 
 */  
public class DogMother implements AnimalMother {  

    @Override  
    public Animal giveBirth() {  
        // TODO Auto-generated method stub  
        Animal dog=new Dog();  
        System.out.println("狗母亲生了一只小狗");  
        return dog;  
    }  

}  

母猫类:

package com.factory.impl;  

import com.bean.Animal;  
import com.bean.Cat;  
import com.factory.AnimalMother;  

/** 
 * 猫母亲 生猫咪 
 * @author Lyon Yao 
 * 
 */  
public class CatMother implements AnimalMother {  

    @Override  
    public Animal giveBirth() {  
        // TODO Auto-generated method stub  
        Animal cat=new Cat();  
        System.out.println("猫母亲生了一只小猫眯");  
        return cat;  
    }  

}  

三、抽象工厂模式:

  • 前面工厂方法模式是比较具体的,是猫肯定生的是小猫,这是不会有问题的,是具体的,那么抽象工厂它所产生的就不是那么具体,产生的对象可能是没有共同特性的。譬如说 一只奶羊不仅仅能够生小羊,同时也能生产羊奶,但小羊是动物,羊奶是食物。

例子如下:

总工厂:

package com.factory;  

import com.bean.Milk;  

/** 
 * 能产奶的 动物母亲 
 * 这里继承 AnimalMother 实现 生育小动物  产奶在此接口声明 构成抽象工厂总接口 
 * @author Lyon Yao 
 * 
 */  
public interface MilkAnimalMother extends AnimalMother {  
    /** 
     * 产奶 
     * @return 
     */  
    public Milk produceMilk();  
}  

奶羊:

package com.factory.impl;  

import com.bean.Animal;  
import com.bean.Milk;  
import com.bean.Sheep;  
import com.bean.SheepMilk;  
import com.factory.MilkAnimalMother;  

/** 
 * 奶羊 
 * @author Lyon Yao 
 * 
 */  
public class SheepMilkMother implements MilkAnimalMother{  

    @Override  
    public Animal giveBirth() {  
        // TODO Auto-generated method stub  
        Animal sheep=new Sheep();  
        System.out.println("奶羊生了一只小羊");  
        return sheep;  
    }  

    @Override  
    public Milk produceMilk() {  
        // TODO Auto-generated method stub  
        Milk milk=new SheepMilk();  
        System.out.println("奶羊生产了羊奶");  
        return milk;  
    }  

}  

奶牛:

 package com.factory.impl;  

import com.bean.Animal;  
import com.bean.Cattle;  
import com.bean.CattleMile;  
import com.bean.Milk;  
import com.factory.MilkAnimalMother;  

/** 
 * 奶牛() 
 * @author Lyon Yao 
 * 
 */  
public class CattleMilkMother implements MilkAnimalMother {  

    @Override  
    public Animal giveBirth() {  
        // TODO Auto-generated method stub  
        Cattle cattle=new Cattle();  
        System.out.println("奶牛生了一只小牛");  
        return cattle;  
    }  

    @Override  
    public Milk produceMilk() {  
        // TODO Auto-generated method stub  
        Milk milk=new CattleMile();  
        System.out.println("奶牛生产了牛奶");  
        return milk;  
    }  
}  

下面是测试例子:

package com.test;  

import org.junit.Test;  

import com.bean.Animal;  
import com.bean.Cat;  
import com.bean.Dog;  
import com.factory.AnimalMother;  
import com.factory.MilkAnimalMother;  
import com.factory.impl.CatMother;  
import com.factory.impl.CattleMilkMother;  
import com.factory.impl.DogMother;  
import com.factory.impl.SheepMilkMother;  
import com.factory.sta.StaticFatory;  

/** 
 * 测试类 
 *  
 * @author Lyon Yao 
 *  
 */  
public class TestCase {  
    /** 
     * 静态工厂类 测试 
     */  
    @Test  
    public void staticFactoryTest() {  
        Animal ani1=(Animal) StaticFatory.getInstance(Cat.class.getName());  
        System.out.println(ani1.getName());  
        ani1.eat();  
        ani1=(Animal) StaticFatory.getInstance(Dog.class.getName(),"dog");  
        System.out.println(ani1.getName());  
        ani1.eat();  
    }  
    /** 
     * 工厂方法模式测试 
     */  
    @Test  
    public void methodFactoryTest(){  
        AnimalMother mother=new CatMother();  
        mother.giveBirth();  
        mother=new DogMother();  
        mother.giveBirth();  
    }  
    /** 
     * 抽象工厂模式测试 
     */  
    @Test  
    public void abstrFactoryTest(){  
        MilkAnimalMother mother=new SheepMilkMother();  
        mother.giveBirth();  
        mother.produceMilk();  
        mother=new CattleMilkMother();  
        mother.giveBirth();  
        mother.produceMilk();  
    }  
}  

控制台输出:

null

I like to eat fish!

dog

I like to eat bone!

猫母亲生了一只小猫眯

狗母亲生了一只小狗

奶羊生了一只小羊

奶羊生产了羊奶

奶牛生了一只小牛

奶牛生产了牛奶

猜你喜欢

转载自blog.csdn.net/weixin_37509652/article/details/80951301