工厂模式以及代理模式

Posted wuzhilong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了工厂模式以及代理模式相关的知识,希望对你有一定的参考价值。

工厂模式:

工厂模式是一种创建模式,:什么是创建,我们知道Java是面向对象的语言,那么我们想使用类中的方法以及属性,那么我们需要创建对象才能调用,那么我们我们必须:A a = new A();来创建实例,我们的工厂模式就是使用工厂来帮我们创建对象。工厂模式主要是为创建对象提供了接口:工厂模式分为3类:简单工厂 、工厂方法、抽象工厂、工厂模式我们在什么时候使用呢?

1.在编码时不能预见需要创建那种对象。

2.系统不应依赖于产品类实例如何被创建,组合、和表达的细节。

一、简单工厂模式:

  这个模式很简单,使用的业务比较简单的情况下;

由3种角色组成:

  工厂类角色::这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现

 抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现

具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现

package com.factory.simple;

/**
 * 水果接口
 */
public interface Fruitable {

//     水果的功能
     void WhatIm();

}
package com.factory.simple;

/**
 * @author :wuzhilong
 * @date:2018年10月25日
 */
public class Apple implements Fruitable {




    @Override
    public void WhatIm() {

    }
}
package com.factory.simple;

/**
 * @author :wuzhilong
 * @date:2018年10月25日
 */
public class FruitFactory {

   //工厂方法
    public Fruitable createFruit(String type){

        if("apploe".equals (type)){

            return new Apple ();
        }else if("Pear".equals (type)){

            return new Pear ();

        }

        return null;
    }

}

 

工厂方法模式:

1、抽象工厂角色:这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
2、具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。在java中它由具体的类来实现。
3、抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
4、具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。

 

package com.factory.method;

/**
 * 工厂接口
 */
public interface FactoryInterface {

    Fruit  createFruit();

}
package com.factory.method;

/**
 * @author :wuzhilong
 * @date:2018年10月25日
 * 每个产品的具体工厂
 */
public class AppleFactory implements FactoryInterface {

    @Override
    public Fruit createFruit() {
        return new Apple ();
    }
}
package com.factory.method;

/**
 * @author :wuzhilong
 * @date:2018年10月25日
 * 每个产品的具体工厂
 */
public class PearFactory implements FactoryInterface {

    @Override
    public Fruit createFruit() {
        return new Pear ();
    }
}
package com.factory.method;

/**
 * @author :wuzhilong
 * @date:2018年10月25日
 * 水果类
 */
public abstract class Fruit {


}
package com.factory.method;

/**
 * @author :wuzhilong
 * @date:2018年10月25日
 */
public class Apple extends Fruit {


}
package com.factory.method;

/**
 * @author :wuzhilong
 * @date:2018年10月25日
 */
public class Pear extends Fruit {
}

 

抽象工厂模式:

1.系统中有多个产品族,而系统一次只可能消费其中一族产品
2.同属于同一个产品族的产品一起使用时。
来看看抽象工厂模式的各个角色(和工厂方法的如出一辙):
抽象工厂角色:这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。在java中它由具体的类来实现。
抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。

 

package com.factory.abs;

/**
 * 产品接口
 */
public interface ThinkPadInterface {

    public void show();



}
package com.factory.abs;

/**
 * @author :wuzhilong
 * @date:2018年10月25日
 * 具体的产品
 */
public class ThinkPadE implements ThinkPadInterface {

    @Override
    public void show() {

    }
}
package com.factory.abs;

/**
 * @author :wuzhilong
 * @date:2018年10月25日
 * 具体的产品
 */
public class ThinkPadT implements ThinkPadInterface {

    @Override
    public void show() {

    }
}
package com.factory.abs;

/**
 * 工厂接口
 */
public interface FactoryInterface {

    public ThinkPadE createThinkPad();

    public ThinkPadT createThinkPadE();

}
package com.factory.abs;

/**
 * @author :wuzhilong
 * @date:2018年10月25日
 * 工厂
 */
public class Factory implements FactoryInterface{

    @Override
    public ThinkPadE createThinkPad() {
        return new ThinkPadE ();
    }

    @Override
    public ThinkPadT createThinkPadE() {
        return new ThinkPadT ();
    }
}

 

 

代理模式:

什么是代理模式:

Proxy模式又叫代理模式,是构造型的模式之一,它可以为其他对象提供一种代理(Proxy)以控制对这个对象的访问。

所谓代理,是指具有与代理元(被代理的对象)具有相同的接口的类,客户端必须通过代理与被代理的目标类交互,而代理一般在交互的过程中(交互前后)进行某些特别的处理。

代理模式结构图:

技术分享图片

 

  

代理模式的实现

代理模式可以有两种实现的方式,一种是静态代理类,另一种是各大框架都喜欢的动态代理

静态代理:

package com.wuzhilong.proxy;

public interface ISinger {

    public void sing();
}
package com.wuzhilong.proxy;

/**
 * 目标对象实现某一接口
 */
public class Singer implements ISinger{



    public void sing(){
        System.out.println ("唱一首歌......");

    }
}
package com.wuzhilong.proxy;

/**
 * 代理对象和目标对象实现相同接口
 */
public class SingerProxy implements  ISinger {

    //接收目标对象,来调用sing方法

    private  ISinger singer;

    public SingerProxy(ISinger singer) {
        this.singer = singer;
    }

    //对目标对象的sing方法进行扩展
    @Override
    public void sing() {

        System.out.println ("向观众问好");
        singer.sing ();
        System.out.println ("谢谢大家");


    }
}

测试:

package com.wuzhilong.proxy;

/**
 * 静态代理模式
 */
public class Demo {


    public static void main(String[] args) {
        //目标对象
        ISinger iSinger = new Singer ();

        //代理对象
        ISinger iSinger1 = new SingerProxy (iSinger);

        iSinger1.sing ();



    }




}

总结:其实这里做的事情无非就是,创建一个代理类SingerProxy,继承了ISinger接口并实现了其中的方法。只不过这种实现特意包含了目标对象的方法,正是这种特征使得看起来像是“扩展”了目标对象的方法。假使代理对象中只是简单地对sing方法做了另一种实现而没有包含目标对象的方法,也就不能算作代理模式了。所以这里的包含是关键。

  缺点:这种实现方式很直观也很简单,但其缺点是代理对象必须提前写出,如果接口层发生了变化,代理对象的代码也要进行维护。如果能在运行时动态地写出代理对象,不但减少了一大批代理类的代码,也少了不断维护的烦恼,不过运行时的效率必定受到影响。这种方式就是接下来的动态代理。

 

动态代理(JDK代理):

package com.wuzhilong.jdkproxy;

public interface ISinger {

    public void sing();
}
package com.wuzhilong.jdkproxy;

import com.wuzhilong.jdkproxy.ISinger;

/**
 * 目标对象实现某一接口
 */
public class Singer implements ISinger {



    public void sing(){
        System.out.println ("唱一首歌......");

    }
}
package com.wuzhilong.jdkproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class SingerProxy implements InvocationHandler {
    //需要代理的真实对象
    private Object subject;
//    构造方法,给我们要代理的真实对象赋初值

    public SingerProxy(Object subject) {
        this.subject = subject;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println ("向观众问好");

//        执行目标类的方法
         method.invoke (subject,args);

        System.out.println ("谢谢大家");

        return null;
    }
}
package com.wuzhilong.jdkproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class Demo {


    public static void main(String[] args) throws Exception{
         //代理的真实对象
        ISinger singer = new Singer ();

        //    我们要代理哪个真实对象,就将该对象传进去,最后是通过该真实对象来调用其方法的
        InvocationHandler invocationHandler = new SingerProxy (singer);

        /*
         * 通过Proxy的newProxyInstance方法来创建我们的代理对象,我们来看看其三个参数
         * 第一个参数 handler.getClass().getClassLoader() ,我们这里使用handler这个类的ClassLoader对象来加载我们的代理对象
         * 第二个参数realSubject.getClass().getInterfaces(),我们这里为代理对象提供的接口是真实对象所实行的接口,表示我要代理的是该真实对象,这样我就能调用这组接口中的方法了
         * 第三个参数handler, 我们这里将这个代理对象关联到了上方的 InvocationHandler 这个对象上
         */

        ISinger singerProxy =(ISinger)  Proxy.newProxyInstance (invocationHandler.getClass ().getClassLoader (),singer.getClass ().getInterfaces (),invocationHandler);
         //通过代理对象执行方法
        singerProxy.sing ();





    }
}

 










以上是关于工厂模式以及代理模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式

Java学习之动态代理

设计模式系列---简单工厂工厂方法抽象工厂

代理模式+简单工厂或代理模式+策略模式实现开通推广功能

设计模式---(简单工厂模式,工厂模式,抽象工程模式),单例模式,代理模式,装饰器

设计模式的分类以及6大原则