3 mins Design Pattern - Proxy Pattern

本文介绍了Java编程中的静态代理模式,通过电影明星和代理经纪人的例子展示了如何使用代理类来包裹目标对象,实现额外的功能,如在拍摄前后收取费用。静态代理模式的缺点在于需要为每个目标对象创建单独的代理类。

1. Introduction

        In real life, let's assume that you are a movie director. If you want to ask Jackie Chen to act in your new film "Rookie Blue", you would not directly meet Jackie but his agent first. How much you need to pay Jackie before he comes and after the film ends are all discussed with Jackie's agent, while Jackie is only focusing on playing in the movie. 

       In programming, we usually have the same logic as we need to create a proxy class to do extra work for our object. Clients can only access the proxy instead of the target object directly. We called it the "Proxy Pattern" in Java Programming. Here let's try to achieve our example using Java.

 2. Static Proxy Pattern

First, we need to create the interface of the moive star; This class has only one method.

public interface MovieStar {
    
    public void act(String movie);
}

Then, we created a new class called Jackie to implement our interface;

public class Jackie implements MovieStar{
    @Override
    public void act(String movie) {
        System.out.println("Act in movie"+movie);
    }
}

The next step is to construct the agent class:

public class MovieAgent implements MovieStar{
    //target object using injection
    private MovieStar star;
    
    public MovieAgent(MovieStar star){
        this.star = star;
    }
    
    public void prePaid(){
        System.out.println("Pre-Paid $500000 before filming");
    }
    
    public void remindPaid(){
        System.out.println("Pay $6000000 after filming");
    }

    @Override
    public void act(String movie) {
        prePaid();
        star.act("Rookie Chen");
        remindPaid();
    }
}

Here, we will inject our target object into the proxy class. So, from the outside, clients will only have access to the agent class while the real star play is Jackie himself. Another functions the agent play is receiving money before and after the movie. Finally, we will achieve this in our test class.

public class Main {
    public static void main(String[] args) {
        MovieAgent agent = new MovieAgent(new Jackie());
        agent.act("Rookie Blue");
    }
}

This is the result:

Pre-Paid $500000 before filming
Act in movieRookie Blue
Pay $6000000 after filming

Conclusion

        This is what we called "Proxy Pattern" design. The core concept of proxy pattern is using a proxy class to "wrap" our target object to perform extra functions or methods. What we showed here is called the "Static Proxy Pattern" the disadvantage of the static proxy pattern is we need to create a unique proxy class for every target object. To make our proxy pattern easier, we have another method called "Dynamic Proxy Pattern", which I will discuss in my following tutorial.

    

import vuetify, { transformAssetUrls } from "vite-plugin-vuetify"; import versionUpdatePlugin from "./plugins/versionUpdatePlugin"; import viteCompression from "vite-plugin-compression"; import cssnano from "cssnano"; // PWA Config const shortTitle = "Xescort.net"; const description = "The best incall & outcall independent escort, 100% real escort and real-name verification, the best dating experience, regardless of gender, age, region or other more requirements can be met."; const themeColor = "#4f46e5"; // https://v3.nuxtjs.org/api/configuration/nuxt.config export default defineNuxtConfig({ modules: [ "@nuxtjs/tailwindcss", "@vite-pwa/nuxt", "@pinia/nuxt", "@pinia-plugin-persistedstate/nuxt", "@nuxt/image", "nuxt-vitalizer", async (options, nuxt) => { nuxt.hooks.hook("vite:extendConfig", (config) => { config.plugins ||= []; config.plugins.push(vuetify()); }); }, ], postcss: { plugins: { "@fullhuman/postcss-purgecss": { content: ["./pages/**/*.vue", "./components/**/*.vue", "./layouts/**/*.vue", "./app.vue"], safelist: [ /^v-/, // 保留所有 Vuetify 类名 /^mdi-/, /--text$/, /--bg$/, /^theme--/, ], }, }, }, image: { formats: ["webp", "avif"], screens: { xs: 320, sm: 640, md: 768 }, presets: { cover: { modifiers: { fit: "cover", format: "webp" } }, }, // domains: ["https://assets.xescort.net"], }, build: { analyze: { analyzerMode: "static", }, transpile: ["vuetify", "@fancyapps/ui", "@nuxt/image"], }, ssr: true, // import styles experimental: { externalVue: false, }, css: [ "vue-snap/dist/vue-snap.css", "@/assets/main.scss", "@/assets/icons/iconfont.css", "@/assets/icons/bootstrap-icons.css", ], devtools: { enabled: true }, routeRules: { "/**": { appMiddleware: ["cache"], }, }, // enable takeover mode typescript: { shim: false }, nitro: { compressPublicAssets: true, prerender: { // crawlLinks: true, // 自动爬取页面链接 routes: [], // 入口页面 ignore: ["/_ipx/**"] /* dynamic routes */, }, routeRules: { "/**": { // cache: false, // headers: { // "Cache-Control": "no-cache, no-store, must-revalidate", // }, }, "/api/**": { cache: { swr: true, maxAge: 60, }, }, // 60秒后重新验证 "/": { prerender: false, // 预渲染首页 isr: 3600, // swr: 60, headers: { "Cache-Control": "public, max-age=3600, s-maxage=3600", // 缓存1小时 }, }, "/categories/[type]/[args]": { prerender: false, // 预渲染分类页面 isr: 3600, swr: 600, headers: { "Cache-Control": "public, max-age=3600, s-maxage=3600", // 缓存1小时 }, }, "/search": { prerender: false, // 预渲染搜索页面 isr: 3600, swr: 600, headers: { "Cache-Control": "public, max-age=3600, s-maxage=3600", // 缓存1小时 }, }, "/details/[tag]/[identity]": { prerender: false, isr: 3600, swr: 600, headers: { "Cache-Control": "public, max-age=3600, s-maxage=3600", // 缓存1小时 }, }, "/escorts/[country]": { prerender: false, // 预渲染所有 escort 页面 isr: 3600, swr: 600, headers: { "Cache-Control": "public, max-age=3600, s-maxage=3600", // 缓存1小时 }, }, "/escorts/[country]/[state]": { prerender: false, // 预渲染所有 escort 页面 isr: 3600, swr: 600, headers: { "Cache-Control": "public, max-age=3600, s-maxage=3600", // 缓存1小时 }, }, "/escorts/[country]/[state]/[city]": { prerender: false, // 预渲染所有 escort 页面 isr: 3600, swr: 600, headers: { "Cache-Control": "public, max-age=3600, s-maxage=3600", // 缓存1小时 }, }, }, }, // Based on docs found here - https://vuetifyjs.com/en/getting-started/installation/#using-nuxt-3 vite: { css: { preprocessorOptions: { scss: { api: "modern-compiler", }, }, // postcss: { // plugins: [ // cssnano({ // preset: ["default", { discardComments: { removeAll: true } }], // }), // ], // }, }, optimizeDeps: { include: ["vuetify", "@fancyapps/ui"], }, build: { modulePreload: false, sourcemap: false, emptyOutDir: true, // 强制清空输出目录 rollupOptions: { output: { format: "es", manualChunks: (id) => { if (id.includes(".scss")) { return "style"; } if (id.includes("node_modules")) { return "vendor"; } }, }, }, }, plugins: [ viteCompression({ algorithm: "gzip", ext: ".gz", threshold: 2048, // Only compress files larger than 10KB }), versionUpdatePlugin(), vuetify({ autoImport: true, }), ], vue: { template: { transformAssetUrls, }, }, // server: { // // host: "0.0.0.0", // Removed as it is not allowed in the current type // proxy: { // "/api": { // target: "https://www.xkwsb.top", // changeOrigin: true, // // rewrite: (path) => path.replace(/^\/api/, ""), // }, // }, // }, define: { "process.env.DEBUG": false, }, }, // devServer: { // https: { // cert: "./certs/cert.pem", // key: "./certs/dev.pem", // }, // }, runtimeConfig: { isServer: true, baseUrl: process.env.NUXT_BASE_URL, port: process.env.PORT || "8000", public: { wsUrl: process.env.NUXT_WS_URL, chatWs: process.env.NUXT_CHAT_WS, chatApi: process.env.NUXT_CHAT_API, port: process.env.PORT || "8000", baseUrl: process.env.NUXT_BASE_URL, gClient: process.env.GOOGLE_CLIENT_ID, }, }, vitalizer: { delayHydration: { hydrateOnEvents: ["click", "touchstart"], idleCallbackTimeout: 2000, postIdleTimeout: 1000, }, disablePrefetchLinks: "dynamicImports", disablePreloadLinks: true, disableStylesheets: "entry", }, app: { head: { htmlAttrs: { lang: "en", }, meta: [ { name: "theme-color", content: themeColor }, { name: "mobile-web-app-capable", content: "yes" }, { name: "rating", content: "adult" }, { name: "robots", content: "noarchive" }, { name: "referrer", content: "no-referrer" }, ], link: [ { rel: "stylesheet", href: "https://cdn.jsdelivr.net/npm/@mdi/font@6.9.96/css/materialdesignicons.min.css", }, { rel: "icon", type: "image/x-icon", href: "/icons/favicon.ico" }, { rel: "apple-touch-icon", href: "/icons/apple-touch-icon.png" }, { rel: "alternate", href: "https://www.xescort.net", hreflang: "x-default" }, { rel: "preconnect", href: "https://api.iconify.design" }, { rel: "preconnect", href: "https://assets.xescort.net" }, { rel: "dns-prefetch", href: "https://api.iconify.design" }, ], // // DNS 预解析 Vue 官方 CDN // { rel: "dns-prefetch", href: "https://unpkg.com" }, // // 预解析常用 CDN(按需添加) // { rel: "dns-prefetch", href: "https://cdn.jsdelivr.net" }, // { rel: "dns-prefetch", href: "https://fonts.googleapis.com" }, // // 推荐同时配置 TCP 预连接 // { rel: "preconnect", href: "https://unpkg.com", crossorigin: "anonymous" }, script: [ // { // src: "https://unpkg.com/vue@3/dist/vue.global.prod.js", // defer: true, // 异步加载 // tagPosition: "bodyClose", // }, // { // src: "https://www.googletagmanager.com/gtag/js?id=G-5VCS4RBFF2", // tagPosition: "bodyClose", // tagPriority: "low", // }, // { // type: "text/javascript", // innerHTML: // "window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-5VCS4RBFF2');", // tagPosition: "bodyClose", // tagPriority: "low", // }, ], }, }, pwa: { includeAssets: ["favicon.ico", "*.txt"], manifest: { name: shortTitle, short_name: shortTitle, description: description, theme_color: themeColor, lang: "en", background_color: "#ffffff", icons: [ { src: "/icons/pwa-192x192.png", sizes: "192x192", type: "image/png", purpose: "any", }, { src: "/icons/pwa-512x512.png", sizes: "512x512", type: "image/png", purpose: "any", }, { src: "/icons/pwa-maskable-192x192.png", sizes: "192x192", type: "image/png", purpose: "maskable", }, { src: "/icons/pwa-maskable-512x512.png", sizes: "512x512", type: "image/png", purpose: "maskable", }, ], }, workbox: { globPatterns: ["**/*.{js,css,html,png,webp,gif,jpg,jpeg,svg,ico}"], globIgnores: ["**/icons/iconfont.css", "**/icons/bootstrap-icons.css"], runtimeCaching: [ { urlPattern: ({ request }) => request.destination === "image", handler: "CacheFirst", options: { cacheName: "images", expiration: { maxEntries: 50, maxAgeSeconds: 30 * 24 * 60 * 60, // 30 days }, }, }, { urlPattern: ({ request }) => request.destination === "script" || request.destination === "style", handler: "StaleWhileRevalidate", options: { cacheName: "scripts-styles", expiration: { maxEntries: 20, maxAgeSeconds: 1 * 24 * 60 * 60, // 1 days }, }, }, ], }, }, compatibilityDate: "2025-08-12", }); 帮我分析下这个nuxt3的配置文件 修改哪些地方可以优化项目
08-20
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值