精华内容
下载资源
问答
  • 外观模式-Facade

    2017-05-17 11:16:36
    源码下载地址 代码 基础的类 外观类 客户端测试 运行结果前言 Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to...


    前言

    Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.

    要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。外观模式提供一个高层次的接口,使得子系统更易为使用。


    UML

    这里写图片描述


    题目

    请使用外观模式(Facade)模拟基金公司代买股票(Stock)、
    国债(NationalDebt)、房地产(Realty)的实例
    股票有两种,分别为高风险高收益股票和低风险低收益股票;
    股票、基金、国债都有2个方法:买入(buy)和卖出(sell)
    买入和卖出都用输出语句表示即可。
    (比如房地产的buy函数就输出:房地产买入;房地产的sell函数就输出:房地产卖出)
    基金公司为用户定制两种金融方案,分别是:
    一、高风险方案:
    包含高风险买入(BuyHighRiskFund)和高风险卖出(SellHighRiskFund)两方法
    调用的是高风险高收益股票和房地产对应的买,卖函数。
    一、低风险方案:
    包含低风险买入(BuyLowRiskFund)和低风险卖出(SellLowRiskFund)两方法。
    调用的是低风险低收益股票和国债对应的买,卖函数。
    

    源码下载地址

    GitHub:https://github.com/YEN-GitHub/PatternDemo/tree/master/src/StructuralPattern/FacadePattern


    代码

    基础的类

    package StructuralPattern.FacadePattern.demo1;
    
    /**
     * Created by yangenneng on 2017-05-17 10:43
     * Abstract:股票接口
     */
    public interface Stock {
    
        public void buy() ;
    
        public void sell() ;
    }
    
    package StructuralPattern.FacadePattern.demo1;
    
    /**
     * Created by yangenneng on 2017-05-17 10:46
     * Abstract:高风险股票
     */
    public class HighStock implements Stock{
    
        @Override
        public void buy() {
            System.out.println("购买高风险股票");
        }
    
        @Override
        public void sell() {
            System.out.println("卖出高风险股票");
        }
    }
    
    package StructuralPattern.FacadePattern.demo1;
    
    /**
     * Created by yangenneng on 2017-05-17 10:46
     * Abstract:高风险股票
     */
    public class LowStock implements Stock{
    
        @Override
        public void buy() {
            System.out.println("购买低风险股票");
        }
    
        @Override
        public void sell() {
            System.out.println("卖出低风险股票");
        }
    }
    
    package StructuralPattern.FacadePattern.demo1;
    
    /**
     * Created by yangenneng on 2017-05-17 10:48
     * Abstract:国债
     */
    public class NationalDebt  {
    
        public void buy() {
            System.out.println("购买国债");
        }
    
        public void sell() {
            System.out.println("卖出国债");
        }
    }
    
    package StructuralPattern.FacadePattern.demo1;
    
    /**
     * Created by yangenneng on 2017-05-17 10:49
     * Abstract:房地产
     */
    public class Realty {
        public void buy() {
            System.out.println("购买房地产");
        }
    
        public void sell() {
            System.out.println("卖出房地产");
        }
    }
    

    外观类

    package StructuralPattern.FacadePattern.demo1;
    
    /**
     * Created by yangenneng on 2017-05-17 10:59
     * Abstract:方案接口
     */
    public interface Scheme {
        public void buyFund();  //购买股票
    
        public void sellFund(); //卖出股票
    }
    
    package StructuralPattern.FacadePattern.demo1;
    
    import java.awt.image.ImageConsumer;
    
    /**
     * Created by yangenneng on 2017-05-17 10:53
     * Abstract:高风险方案
     */
    public class HighRiskFund implements Scheme {
    
        protected Stock stock=new HighStock(); //高风险股票
        private Realty realty=new Realty();  //房地产
    
        @Override
        public void buyFund() {
            System.out.println("---------------购买高风险方案---------------");
            stock.buy();
            realty.buy();
        }
    
        @Override
        public void sellFund() {
            System.out.println("---------------卖出高风险方案---------------");
            stock.sell();
            realty.sell();
        }
    }
    
    package StructuralPattern.FacadePattern.demo1;
    
    /**
     * Created by yangenneng on 2017-05-17 10:57
     * Abstract:低风险方案
     */
    public class LowRiskFund implements Scheme {
    
        protected Stock stock=new LowStock();  //低风险股票
        protected NationalDebt nationalDebt=new NationalDebt();//国债
    
        @Override
        public void buyFund() {
            System.out.println("---------------购买低风险方案---------------");
            stock.buy();
            nationalDebt.buy();
        }
    
        @Override
        public void sellFund() {
            System.out.println("---------------卖出低风险方案---------------");
            stock.sell();
            nationalDebt.sell();
        }
    }
    

    客户端测试

    package StructuralPattern.FacadePattern.demo1;
    
    /**
     * Created by yangenneng on 2017-05-17 10:58
     * Abstract:客户端测试代码
     */
    public class Client {
        public static void main(String[] args) {
            Scheme scheme1=new HighRiskFund();
            scheme1.buyFund();
            scheme1.sellFund();
    
            Scheme scheme2=new LowRiskFund();
            scheme2.buyFund();
            scheme2.sellFund();
        }
    }
    

    运行结果

    这里写图片描述

    展开全文
  • 外观模式facade

    2019-03-24 01:31:04
    NULL 博文链接:https://hnzhoujunmei.iteye.com/blog/1033285
  • 博客原文:Laravel 创建自己的 Facade 前言 laravel 提供了一个灵活的模式,那就是 facade 。框架内部的 DB、Auth、File 等功能也有相关的 facade 实现。那么,该如何写自己的 facade 呢? Facade 是什么? 首先,...

    博客原文:Laravel 创建自己的 Facade

    前言

    laravel 提供了一个灵活的模式,那就是 facade 。框架内部的 DB、Auth、File 等功能也有相关的 facade 实现。那么,该如何写自己的 facade 呢?

    Facade 是什么?

    首先,facade 并不是 laravel 独有的东西,它就是设计模式中的外观模式(Facade)。
    当然,这里就不长篇大论去讨论外观模式的定义了。这篇文章写的很不错 : 设计模式(九)外观模式Facade(结构型)
    那么,laravel 的 facade 做了什么?
    同样的, laravel 实现了外观模式的开关功能,并且使用魔术方法 __callstatic 实现了静态方式调用、动态创建对象的功能。参考 (官方文档)

    当然你可能觉得这些概念很抽象,都什么玩意。那么其实简单的讲,laravel 的 facade 就是将某些功能封装成工具类,而且能以静态方式调用工具类的方法。

    建立自己的 facade

    首先、以 laravel 5.1 框架,我之前写过的 Geoip facade 为例,说一下怎么去建立自己的 facade。

    下载 geoip 扩展

    geoip 是一个可以更具 IP 获取国家、地域、城市信息的 PHP 扩展,基于 maxmind 数据库。 github 在此

    首先,为 laravel 添加 geoip 扩展。
    打开 composer.json,添加 “geoip2/geoip2”: “~2.0” 到 require。
    项目根目录运行 composer update ( 需要安装 composer )更新一下,geoip 的依赖和软件包就被下载到 vendor 文件夹中了。

    然后下载 geoip 依赖的数据库,免费库的地址 : GeoLite2

    我下载了 GeoLite2 Country 和 GeoLite2 City 库,放到了 storage/geoipdb 中。

    建立 facade

    在 app 目录下新建 Facades 文件夹,里面新建 Facades/GeoIP/GeoIP.php 和 Facades/GeoIP/Facade/GeoIP.php (建议每个功能新建一个文件夹区分,比如我这里给 GeoIP 新建一个文件夹,关于GeoIP 的东西全放到这里)
    注意,Facades/GeoIP 下的 GeoIP.php 是你要对 geoip 扩展进行封装的类, Facades/GeoIP/Facade 下的 GeoIP.php 是你的 facade,用来给 laravel 解析使用,这两个文件可以不同名。
    image.png

    Facades/GeoIP/Facade/GeoIP.php 如下

    <?php
    
    namespace App\Facades\GeoIP\Facade;
    
    use Illuminate\Support\Facades\Facade;
    
    class GeoIP extends Facade
    {
        protected static function getFacadeAccessor()
        {
            return 'geoip';
        }
    }
    

    注意你的 facade 现在只有一个方法,返回了一个字符串 ‘geoip’ , 这个字符串是一个标号,用来给 laravel 的服务提供者解析使用的。

    Facades/GeoIP/GeoIP.php 如下(吐槽:写的有点随意)

    <?php
    
    namespace App\Facades\GeoIP;
    
    use GeoIp2\Database\Reader;
    
    class GeoIP
    {
        /**
         * GeoIP country db path (base on storage_path).
         *
         * @var GeoIP
         */
        private $_country_db = 'geoipdb/GeoLite2-Country.mmdb';
    
        /**
         * GeoIP city db path (base on storage_path).
         *
         * @var GeoIP
         */
        private $_city_db = 'geoipdb/GeoLite2-City.mmdb';
    
        /**
         * Instance for GeoIP .
         *
         * @var GeoIP
         */
        private $_instance;
    
        /**
         * Init instance.
         *
         */
        public function init($mode)
        {
            switch ($mode) {
              case 'getCountry':
                $path = $this->_country_db;
                break;
              case 'getCity':
                $path = $this->_city_db;
                break;
              default:
                break;
            }
    
            $this->_instance = new Reader(storage_path($path));
        }
    
        /**
         * Get Country infomations.
         *
         * @param  String  $ip
         * @return Array
         */
        public function getCountry($ip)
        {
          $this->init(__FUNCTION__);
    
          $record = $this->_instance->country($ip);
    
          // 国家信息
          $data['iso_code'] = $record->country->isoCode;
          $data['country_name'] = $record->country->name;
          $data['country_name_zh_cn'] = $record->country->names['zh-CN'];
    
          return $data;
        }
     
     /**
         * Get City infomations.
         *
         * @param  String  $ip
         * @return Array
         */
        public function getCity($ip)
        {
          $this->init(__FUNCTION__);
    
          $record = $this->_instance->city($ip);
    
          $data['iso_code'] = $record->country->isoCode;
          $data['country_name'] = $record->country->name;
          $data['country_name_zh_cn'] = $record->country->names['zh-CN'];
    
          // 省、州信息
          $data['sub_division_name'] = $record->mostSpecificSubdivision->name;
          $data['sub_division_name_zh_cn'] = $record->mostSpecificSubdivision->names['zh-CN'];
          $data['sub_division_code'] = $record->mostSpecificSubdivision->isoCode;
    
          // 城市信息
          $data['city_name'] = $record->city->name;
          $data['postal_code'] = $record->postal->code;
    
          // 经纬度
          $data['latitude'] = $record->location->latitude;
          $data['longitude'] = $record->location->longitude;
    
          return $data;
        }
    }
    

    OK,现在 geoip 的常用功能已经封装到方法中了。

    注册服务

    完成了 facade 的创建和功能封装,下面就要使用它了。自己创建的 facade 要在 laravel 使用是要进行注册的,以便 laraval 在启动时能自动注入依赖(请看 laravel 的依赖注入简介 : laravel 依赖注入 学院君)

    编写服务提供者

    在 app/Providers 下新建 FacadesServiceProvider.php
    可以手动建,也可以用 artisan 命令来生成,随你喜欢。
    app/Providers/FacadesServiceProvider.php 代码如下:

    <?php
    
    namespace App\Providers;
    
    use App\Service\ApiService;
    use Illuminate\Support\ServiceProvider;
    
    // include the class facade binded
    use App\Facades\GeoIP\GeoIP;
    
    class FacadesServiceProvider extends ServiceProvider
    {
        /**
         * 在容器中注册绑定。
         *
         * @return void
         */
        public function register()
        {
            $this->app->singleton('geoip', function ($app) {
                return new GeoIP($app);
            });
        }
    }
    

    上面代码可知,服务提供者注册时会注册一个单例,标号为 ‘geoip’,也就是我们自己的 facade 返回的那个,然后回调函数会返回一个对象,也就是我们封装 geoip 功能的那个类的实例,不明白的同学可以看看 laravel 的服务提供者和服务容器相关知识哦。(注意要 use 将 facade 和封装类的命名空间引用一下哦)

    注册服务提供者

    laravel 5.1 以上版本的话, config/app.php 中找到 providers 和 aliases ,将你的服务提供者和 facade 别名配置一下 :

    providers 加入 :

    App\Providers\FacadeServiceProvider::class,
    aliases 加入(不用每次都写很长的命名空间前缀) :

    'GeoIP' => App\Facades\GeoIP\Facade\GeoIP::class,
    对于 lumen 5.2 以上,需要在 bootstrap/app.php 中添加
    $app->register(App\Providers\FacadesServiceProvider::class);
    注:放到AppServiceProvider类的register方法里更合理一些
    $this->app->register(App\Providers\FacadesServiceProvider::class);
    注册完毕后,每次使用 facade::function 的时候,laravel 会自动解析 facade, 然后创建一个对象给用户使用,,而无需用户自己去 new 一个对象出来。

    使用
    现在,在任何一个控制器,或者路由的回调函数中,使用

    $res = GeoIP::getCountry('75.101.195.215');
    var_dump($res);
    

    你会发现,facade 已经可以好好工作了,enjoy!

    参考文章

    【1】设计模式(九)外观模式Facade(结构型)
    【2】Laravel 服务容器实例教程 —— 深入理解控制反转(IoC)和依赖注入(DI)
    【3】Laravel 服务提供者实例教程 —— 创建 Service Provider 测试实例

    展开全文
  • Laravel 创建自己的 Facade(转载) 原文:https://segmentfault.com/a/1190000009759459 前言 laravel 提供了一个灵活的模式,那就是 facade 。框架内部的 DB、Auth、File 等功能也有相关的 facade 实现。那么,该...

    Laravel 创建自己的 Facade(转载)

    原文:https://segmentfault.com/a/1190000009759459

    前言

    laravel 提供了一个灵活的模式,那就是 facade 。框架内部的 DB、Auth、File 等功能也有相关的 facade 实现。那么,该如何写自己的 facade 呢?

    Facade 是什么?

    首先,facade 并不是 laravel 独有的东西,它就是设计模式中的外观模式(Facade)。
    当然,这里就不长篇大论去讨论外观模式的定义了。这篇文章写的很不错 : 设计模式(九)外观模式Facade(结构型)
    那么,laravel 的 facade 做了什么?
    同样的, laravel 实现了外观模式的开关功能,并且使用魔术方法 __callstatic 实现了静态方式调用、动态创建对象的功能。参考 (官方文档)

    当然你可能觉得这些概念很抽象,都什么玩意。那么其实简单的讲,laravel 的 facade 就是将某些功能封装成工具类,而且能以静态方式调用工具类的方法。

    建立自己的 facade

    首先、以 laravel 5.1 框架,我之前写过的 Geoip facade 为例,说一下怎么去建立自己的 facade。

    下载 geoip 扩展

    geoip 是一个可以更具 IP 获取国家、地域、城市信息的 PHP 扩展,基于 maxmind 数据库。 github 在此

    首先,为 laravel 添加 geoip 扩展。
    打开 composer.json,添加 “geoip2/geoip2”: “~2.0” 到 require。
    项目根目录运行 composer update ( 需要安装 composer )更新一下,geoip 的依赖和软件包就被下载到 vendor 文件夹中了。

    然后下载 geoip 依赖的数据库,免费库的地址 : GeoLite2

    我下载了 GeoLite2 Country 和 GeoLite2 City 库,放到了 storage/geoipdb 中。

    建立 facade。

    在 app 目录下新建 Facades 文件夹,里面新建 Facades/GeoIP/GeoIP.php 和 Facades/GeoIP/Facade/GeoIP.php (建议每个功能新建一个文件夹区分,比如我这里给 GeoIP 新建一个文件夹,关于GeoIP 的东西全放到这里)
    注意,Facades/GeoIP 下的 GeoIP.php 是你要对 geoip 扩展进行封装的类, Facades/GeoIP/Facade 下的 GeoIP.php 是你的 facade,用来给 laravel 解析使用,这两个文件可以不同名。

    目录结构如图:

    img

    Facades/GeoIP/Facade/GeoIP.php 如下

    <?php
    
    namespace App\Facades\GeoIP\Facade;
    
    use Illuminate\Support\Facades\Facade;
    
    class GeoIP extends Facade
    {
        protected static function getFacadeAccessor()
        {
            return 'geoip';
        }
    }
    

    注意你的 facade 现在只有一个方法,返回了一个字符串 ‘geoip’ , 这个字符串是一个标号,用来给 laravel 的服务提供者解析使用的。

    Facades/GeoIP/GeoIP.php 如下(吐槽:写的有点随意)

    <?php
    
    namespace App\Facades\GeoIP;
    
    use GeoIp2\Database\Reader;
    
    class GeoIP
    {
        /**
         * GeoIP country db path (base on storage_path).
         *
         * @var GeoIP
         */
        private $_country_db = 'geoipdb/GeoLite2-Country.mmdb';
    
        /**
         * GeoIP city db path (base on storage_path).
         *
         * @var GeoIP
         */
        private $_city_db = 'geoipdb/GeoLite2-City.mmdb';
    
        /**
         * Instance for GeoIP .
         *
         * @var GeoIP
         */
        private $_instance;
    
        /**
         * Init instance.
         *
         */
        public function init($mode)
        {
            switch ($mode) {
              case 'getCountry':
                $path = $this->_country_db;
                break;
              case 'getCity':
                $path = $this->_city_db;
                break;
              default:
                break;
            }
    
            $this->_instance = new Reader(storage_path($path));
        }
    
        /**
         * Get Country infomations.
         *
         * @param  String  $ip
         * @return Array
         */
        public function getCountry($ip)
        {
          $this->init(__FUNCTION__);
    
          $record = $this->_instance->country($ip);
    
          // 国家信息
          $data['iso_code'] = $record->country->isoCode;
          $data['country_name'] = $record->country->name;
          $data['country_name_zh_cn'] = $record->country->names['zh-CN'];
    
          return $data;
        }
     
     /**
         * Get City infomations.
         *
         * @param  String  $ip
         * @return Array
         */
        public function getCity($ip)
        {
          $this->init(__FUNCTION__);
    
          $record = $this->_instance->city($ip);
    
          $data['iso_code'] = $record->country->isoCode;
          $data['country_name'] = $record->country->name;
          $data['country_name_zh_cn'] = $record->country->names['zh-CN'];
    
          // 省、州信息
          $data['sub_division_name'] = $record->mostSpecificSubdivision->name;
          $data['sub_division_name_zh_cn'] = $record->mostSpecificSubdivision->names['zh-CN'];
          $data['sub_division_code'] = $record->mostSpecificSubdivision->isoCode;
    
          // 城市信息
          $data['city_name'] = $record->city->name;
          $data['postal_code'] = $record->postal->code;
    
          // 经纬度
          $data['latitude'] = $record->location->latitude;
          $data['longitude'] = $record->location->longitude;
    
          return $data;
        }
    
    }
    

    OK,现在 geoip 的常用功能已经封装到方法中了。

    注册服务

    完成了 facade 的创建和功能封装,下面就要使用它了。自己创建的 facade 要在 laravel 使用是要进行注册的,以便 laraval 在启动时能自动注入依赖(请看 laravel 的依赖注入简介 : laravel 依赖注入 学院君)

    编写服务提供者

    在 app/Providers 下新建 FacadesServiceProvider.php
    可以手动建,也可以用 artisan 命令来生成,随你喜欢。
    app/Providers/FacadesServiceProvider.php 代码如下:

    <?php
    
    namespace App\Providers;
    
    use App\Service\ApiService;
    use Illuminate\Support\ServiceProvider;
    
    // include the class facade binded
    use App\Facades\GeoIP\GeoIP;
    
    class FacadesServiceProvider extends ServiceProvider
    {
        /**
         * 在容器中注册绑定。
         *
         * @return void
         */
        public function register()
        {
            $this->app->singleton('geoip', function ($app) {
                return new GeoIP($app);
            });
        }
    }
    

    上面代码可知,服务提供者注册时会注册一个单例,标号为 ‘geoip’,也就是我们自己的 facade 返回的那个,然后回调函数会返回一个对象,也就是我们封装 geoip 功能的那个类的实例,不明白的同学可以看看 laravel 的服务提供者和服务容器相关知识哦。(注意要 use 将 facade 和封装类的命名空间引用一下哦)

    注册服务提供者

    laravel 5.1 以上版本的话, config/app.php 中找到 providers 和 aliases ,将你的服务提供者和 facade 别名配置一下 :

    providers 加入 :

    App\Providers\FacadeServiceProvider::class,
    

    aliases 加入(不用每次都写很长的命名空间前缀) :

    'GeoIP' => App\Facades\GeoIP\Facade\GeoIP::class,
    

    对于 lumen 5.2 以上,需要在 bootstrap/app.php 中添加

    $app->register(App\Providers\FacadesServiceProvider::class);
    

    注册完毕后,每次使用 facade::function 的时候,laravel 会自动解析 facade, 然后创建一个对象给用户使用,,而无需用户自己去 new 一个对象出来。

    使用

    现在,在任何一个控制器,或者路由的回调函数中,使用

    copy$res = GeoIP::getCountry('75.101.195.215');
    var_dump($res);
    
    展开全文
  • 外观模式(Facade pattern),是软件工程中常用的一种软件设计模式,它为子系统中的一组接口提供一个统一的高层接口,使得子系统更容易使用。----WIKIPEDIA 个人理解 当一个项目中出现比较杂乱的调用关系时,...

    外观模式(Facade pattern),是软件工程中常用的一种软件设计模式,它为子系统中的一组接口提供一个统一的高层接口,使得子系统更容易使用。----WIKIPEDIA


    个人理解

    当一个项目中出现比较杂乱的调用关系时,类与类之间的耦合关系过于复杂,为了降低耦合度,我们可以采用一个公共的接口与其他类发生耦合,这样可以尽量大的降低外界与该系统的耦合度,同时降低了整个系统的复杂度,外观模式相当于一个公共的入口一样,为使用者敞开大门,暴漏一些必要的接口,方便外界进行调用。通俗来讲就是,有多个不同的类提供了多个访问的接口,外观模式就是要统一将这些接口进行管理。如下面两个图所示。

    使用外观模式:



    案例


    假设这样一个情景:我想做个红烧肉,说下主要的调料需要买:五花肉、油等等,这个不是重点,说一下里面有什么类吧,五花肉的零售商、食材批发商、油的零售商,先拿这三个举例子。三者之间的关系,零售商需要向批发商购置自己需要配备的食材。而我呢,作为一个使用者,只需要去零售商那里去购置即可。


    其中Facade中代码为

    public class Facade {
    
    	private OilRetailer oilRetailer = new OilRetailer();
    
    	private PorkRetailer porkRetailer = new PorkRetailer();
    	
    	/**
    	 * 买猪肉
    	 * @return
    	 */
    	public String getPork(){
    		System.out.println(porkRetailer.getPork());
    		
    		return "Pork";
    	}
    	
    	/**
    	 * 买油
    	 * @return
    	 */
    	public String getOil(){
    		System.out.println(oilRetailer.getOil());
    		
    		return "Oil";
    	}
    }
    
    猪肉零售商
    public class PorkRetailer {
    
    	private WholeSaler wholeSaler = new WholeSaler();
    	
    	public String getPork(){
    		System.out.println(wholeSaler.getProk());
    		return "PorkRetailer-Pork";
    	}
    }
    油零售商

    public class OilRetailer {
    
    	private WholeSaler wholeSaler = new WholeSaler();
    	
    	public String getOil(){
    		System.out.println(wholeSaler.getOil());
    		return "OilRetailer-Oil";
    	}
    }
    

    批发商

    public class WholeSaler {
    
    	public String getProk(){
    		return "WholeSaler-Prok";
    	}
    	
    	public String getOil(){
    		return "WholeSaler-Oil";
    	}
    }
    

    上述代码比较粗糙,综合而言,如果不使用Facade外观模式,那么,WY这个类直接与这些零售商等等的类进行耦合那样的话就会导致系统的复杂,使用了Facade外观模式之后,屏蔽了子系统的一些细节,WY不再和其他的零售商的类进行耦合,只需要和Facade进行耦合即可。


    观察上述类,因为不管是批发商还是零售商,他们的方法基本上一致,那么,我们可以考虑优化一下,通过接口进行进一步的优化。


    引入接口,如果使用过Spring框架的朋友知道可以通过Spring的依赖注入功能实现对象的注入,那么在这种情况下,将大大的减少类与类直接的耦合。

    外观模式的核心类

    public class Facade implements PorkMerchant, OilMerchant{
    
    	private OilMerchant oilRetailer = new OilRetailer();
    
    	private PorkMerchant porkRetailer = new PorkRetailer();
    	
    	/**
    	 * 买猪肉
    	 * @return
    	 */
    	public String getPork(){
    		System.out.println(porkRetailer.getPork());
    		
    		return "Pork";
    	}
    	
    	/**
    	 * 买油
    	 * @return
    	 */
    	public String getOil(){
    		System.out.println(oilRetailer.getOil());
    		
    		return "Oil";
    	}
    }


    适用范围

    1. 当你的系统和子系统中一些模块中多个类发生了耦合,为了减少系统的耦合度建议采用外观模式。

    2. 建立一个层次结构的子树的时候,如果层次间相互依赖比较严重,那么建议采用外观模式降低耦合度。

    3. 子系统相对独立

    优点

    1. 减少系统的相互依赖

    2. 提高系统的灵活性

    3.提高安全性


    源码下载

    源码下载地址


    展开全文
  • 外观模式(facade pattern) 详解本文地址:http://blog.csdn.net/caroline_wendy外观模式(facade pattern): 提供了一个统一的接口, 用来访问子系统中的一群接口. 外观定义了一个高层接口, 让子系统更容易使用.外观模式...
  • 本节将讲述Facade,Proxy、Mediator、Command的统一管家。自定义Facade必须继承Facade,在本示例中自定义Facade名称为ApplicationFacade,这个名称也是pureMVC组织建议的名称。先看代码: Applicationfacade...
  • 《常用开发包下载地址汇总》 下载Jackson http://www.java2s.com/Code/Jar/j/Downloadjacksonjar.htm 下载Simple Logging Facade for Java (SLF4J) https://www.slf4j.org/ 下载Apache Axis2 ...
  • Facade模式要求一个子系统的外部与其内部的通信必须通过一个统一的Facade对象进行。Facade模式提供一个高层次的接口,使得子系统更易于使用。 、 模式结构 模式讨论 Facade模式为一个复杂子系统提供一个简单接...
  • 在《设计模式 - 可复用的面向对象软件》一书中将之描述为“ 为系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用 ”。 模式 需要角色如下: Facade...
  • 许多人发现这很有用,因此他们可以在常用网站上存储密码,或者只是让他们知道他们过去访问或下载的内容。 不同类型的 cookie 跟踪不同的活动。会话 cookie 仅在某人主动浏览网站时使用; 一旦您离开网站,会话 ...
  • MSDN Webcast所有视频讲座的下载地址

    万次阅读 热门讨论 2008-01-28 00:37:00
    标题 难度 评分 时间 讲师 构建安全的应用程序 200 3.5 2004-9-7
  • 下载地址:http://download.csdn.net/detail/jerryshen/8876879 1)本例为Java代码生成器InfinityGPGenerator0.79版,免积分下载 2)支持自动生成JSON Facade 3)请使用本代码生成器的DSL即SGS(标准生成器脚本)...
  • zookeeper官网(可以跳过这些图片上的步骤直接到下载地址上):https://zookeeper.apache.org/ https://www.apache.org/dyn/closer.cgi/zookeeper/ zookeeper下载地址: http://mirro...
  • 今天我们来看看Nutch的源代码中的protocol-http插件,是如何抓取和下载web页面的。...Http类则非常简单,其实可以说是HttpResponse的一个Facade,设置配置信息,然后创建HttpRespose。用户似乎只需要和Http类打交
  • 支付宝接口调用“单笔转账到支付宝账户”的接口调用,一般涉及到下面几个知识点1、生成签名在使用...从网址上可以下载Windows和MAC版本的RSA签名生成工具下载该工具后,解压打开文件夹,运行“RSA签名验签工具.bat”
  • 今天我们来看看Nutch的源代码中的protocol-http插件,是如何抓取和下载web页面的。...Http类则非常简单,其实可以说是HttpResponse的一个Facade,设置配置信息,然后创建HttpRespose。用户似乎只需要和Http类打交...
  • redis官方下载地址:https://redis.io/download,redis 64位下载地址:https://github.com/ServiceStack/redis-windows,本人测试使用的是redis-64.3.0.503版本。 2.解压。安装 下载解压之后,cmd打开命令行,...
  • 自定义日志在loggers.LogInfo 方法使用facade.NewZaplog 和 facade.NewRedislog 切换 数据库 models下定义的文件均需要实现 TableName() string 方法,并将实现该结构体的指针写入到 GetModels 方法中 func ...
  • 完整demo地址:https://download.csdn.net/download/qq_37310110/11559522 一:流程(仅供参考) ab资源的下载更新一般走以下流程: 1.ab设置包名(注意包名规则) 2.当前版本ab打包(如果是通过服务器下载的话...
  • 说明:本工具适用大部分导入导出场景,花点时间搞懂怎么用了之后灰常方便,阅读本文前,建议下载源码后参考着阅读。源码地址:https://gitee.com/xwzhang1/excel-util.git 在使用过程中如果有不懂的地方,请随时在...
  • 简介 Laravel 另一个令人喜欢的地方,是拥有活跃的开发者社区,而...该项目统计了目前 packagist 下载量最高的 50 个 Laravel 扩展包。并把更新脚本放到了github。 项目地址 https://github.com/godruoyi/laravel...
  • cycleGAN | NiceGAN 论文中使用到的 四个 风格转换数据集下载链接: https://people.eecs.berkeley.edu/~taesung_park/CycleGAN/datasets/ 下载界面如下: 持续更新… 欢迎补充…
  • 0.Eclipse下载 EMF,GEF - Graphical Editor Framework,UML2,VE - Visual Editor都在这里下载 http://www.eclipse.org/downloads/index.php 0...
  • use think\facade\Request; class Index extends Controller { protected $middleware = []; public function index() { //这里需要注意该目录是否存在,并且有创建的权限 $zipname = 'test.zip'; //这是要...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,886
精华内容 1,954
关键字:

facade下载地址