zoukankan      html  css  js  c++  java
  • 工厂模式以及代理模式

    工厂模式:

    工厂模式是一种创建模式,:什么是创建,我们知道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课程作业01
    《大道至简》第二章读后感
    《大道至简》第一章读后感
    制作Linux镜像,将腾讯云服务器系统制成镜像
    postman数据驱动
    Navicat Premium 连接Oracle数据库报错 instant Client LIght : unsupported server charcter ser ZHS16GBK
    查看python位数
    AutoItLibrary安装过程中遇到的坑
    hyrobot使用
    有这样一道智力题:“某商店规定:三个空汽水瓶
  • 原文地址:https://www.cnblogs.com/wuzhilong/p/9851548.html
Copyright © 2011-2022 走看看