精华内容
下载资源
问答
  • 所以,简单办法,就是自已构造一个小型 GUI 环境,只针对你应用,与 其他系统无关。 那么,可能有人会说,量体裁衣开发一个适合于自有项目 GUI 环境固然很 好,但这会不会很复杂,是不是会使项目周期拉长...
  •  虽然虚拟现实头戴显示器是下一个消费电子热点,但大家对于其复杂的硬件构造、运行原理可能并不是十分了解。今天,我们就来看看虚拟现实头戴中究竟藏着什么秘密。  基本技术特性  首先,可以肯定...
  • 既能用来开发简单的小东西,也能构造更为复杂的应用。 跨设备,跨浏览器 最初设想中的Bootstrap只支持现代浏览器,不过新版本已经能支持所有主流浏览器(甚至包括IE7)。从Bootstrap 2开始,提供对平板和智能...
  •  第1章 英雄还看今朝—Android简介本章介绍了市场上主流的手机平台,同时也分析了未来手机平台的发展趋势及Android平台的前景  第2章 数风流人物—当前流行游戏类型简介本章以分类的方式简要地介绍了当前流行的...
  • 构建者模式

    2017-04-26 22:55:00
    当要创建的对象很复杂的时候(通常是由很多其他对象组合而成), 我们要将复杂对象的创建过程和这个对象的表示充分分离,这样的好处就是通过一步步的进行复杂对象的构建,由于在每一步的构造过程中都可以引入参数,使得...

    将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示

    当要创建的对象很复杂的时候(通常是由很多其他对象组合而成), 我们要将复杂对象的创建过程和这个对象的表示充分分离,这样的好处就是通过一步步的进行复杂对象的构建,由于在每一步的构造过程中都可以引入参数,使得经过相同的步骤创建最后得到的对象的展示不一样。

    例如说一部手机,先放主板,再放屏幕,再放电池,再放外壳,贴个膜就能卖几千了,每次推出新产品,就换个更好的主板,换个大点的屏幕,再整个大容量电池,贴个超牛B的高透膜,又能卖出个新价钱。就是说,这些步骤都没有变,变的只是每个部分的东西。

    又如:创建一个窗口控件(Widget)时,往往都要初始化UI、初始化动画、初始化信号和槽,这些构造的接口,构造的顺序是固定的,而变化的是具体的实现过程

    建造者模式的定义中构建指的就是生产一个产品的步骤表示就是每个产品部分的具体实现通过Director封装步骤,通过Builder封装产品部分的实现,再把他两隔离开,就能隔离变的,留出不变的供客户端使用。

    Builder模式的关键是其中的Director对象并不是直接返回对象,而是通过一步步进行对象的构建。

     

    构建者模式和抽象工厂模式的比较:

    两者功能相似,都用来创建复杂的对象,但是构建者模式更加强调一步一步构建对象,并通过相同的构建步骤得到不同的结果对象,一般来说构建者模式的对象不是直接返回的,而抽象工厂模式的创建的对象时直接返回的,它强调的是为创建多个相互依赖的对象提供统一的接口

     

    代码:

    #include <iostream>
    #include <string>
    using namespace std;
    
    class House
    {
    public:
        ~House()
        {
            cout << "House 被析构" << endl;
        }
    public:
        void setWall(const string & wall)
        {
            _wall = wall;
        }
    
        void setWindow(const string &window)
        {
            _window = window;
        }
    
        void setDoor(const string &door)
        {
            _door = door;
        }
    
        void show()
        {
            cout << "Wall: " << _wall << " Window: " << _window << " Door: " << _door << endl;
        }
    private:
        string _wall;
        string _window;
        string _door;
    };
    
    class HouseBuilder
    {
    public:
        virtual ~HouseBuilder() {}
        virtual void buildWall() = 0;
        virtual void buildWindow() = 0;
        virtual void buildDoor() = 0;
        virtual House *getHouse() = 0;
    };
    
    // 公寓构建者
    class FlatBuilder : public HouseBuilder
    {
    public:
        FlatBuilder()
        {
            _house = new House;
        }
    
        ~FlatBuilder() 
        {  
            cout << "FlatBuilder 被析构" << endl;;
        }
    
    public:
        virtual void buildWall()
        {
            _house->setWall("Flat wall");
        }
    
        virtual void buildWindow()
        {
            _house->setWindow("Flat window");
        }
    
        virtual void buildDoor()
        {
            _house->setDoor("Flat Door");
        }
    
        virtual House *getHouse()
        {
            return _house;
        }
    
    private:
        House *_house;
    };
    
    // 别墅 构建者
    class VillaBuilder : public HouseBuilder
    {
    public:
        VillaBuilder()
        {
            _house = new House;
        }
    
        ~VillaBuilder()
        {
            cout << "ViallBuilder 被析构" << endl;
        }
    
    public:
        virtual void buildWall()
        {
            _house->setWall("Villa Wall");
        }
    
        virtual void buildWindow()
        {
            _house->setWindow("Villa Window");
        }
    
        virtual void buildDoor()
        {
            _house->setDoor("Villa Door");
        }
    
        virtual House *getHouse()
        {
            return _house;
        }
    
    private:
        House *_house;
    };
    
    class Director
    {
    public:
        Director(HouseBuilder *builder)
        {
            _builder = builder;
        }
        ~Director()
        {
            cout << "Director 被析构" << endl;
        }
    
    public:
        // 封装了房子的创建步骤
        void construct()
        {
            _builder->buildWall();  
            _builder->buildWindow();
            _builder->buildDoor();
        }
    private:
        HouseBuilder *_builder;
    };
    
    void test()
    {
        HouseBuilder *builder = NULL;
        Director *director = NULL;
        House *house = NULL;
    
        //建造公寓
        builder = new FlatBuilder;
        director = new Director(builder);
        director->construct();
        house = builder->getHouse();
        house->show();
        delete house;
        delete builder;
        delete director;
    
        // 建造别墅
        builder = new VillaBuilder;
        director = new Director(builder);
        director->construct();
        house = builder->getHouse();
        house->show();
        delete house;
        delete builder;
        delete director;
    }
    
    int main()
    {
        test();
        cin.get();
        return 0;
    }

     

    参考:

    http://www.cnblogs.com/cxjchen/p/3149897.html

    http://www.2cto.com/kf/201603/492606.html

    转载于:https://www.cnblogs.com/hupeng1234/p/6767468.html

    展开全文
  • 设计模式-构建器模式

    2016-10-16 11:09:21
    构建器模式(Builder)将一个复杂对象构建与它表示分离,使得同样构建过程可以创建不同表示。 当一个类有大量可选参数。例如:用一个类表示手机的各项指标,这些标签中有几个是必需,而其他是可选。...

    构建器模式(Builder)将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

    当一个类有大量的可选参数。例如:用一个类表示手机的各项指标,这些标签中有几个是必需的,而其他的是可选的。那我们如何表示这样的一个类呢?我们习惯的做法是:提供第一个只有必要参数的构造器。第二个构造器有一个可选参数,第三个有两个可选参数,依此类推,最后一个构造器包含所有可选参数。例如(为了简单起见,只显示了三个可选域):

    public class Phone{
        private final String brand;//品牌      required
        private final String model;//型号      required
        private final int battery;//电池电量    optional
        private final float screen;//屏幕尺寸   optional
        private final int pixels;// 像素       optional
    
        public Phone(String brand, String model){
            this(brand,model,0);
        }
    
        public Phone(String brand, String model, int battery){
            this(brand,model,battery,0);
        }
    
        public Phone(String brand, String model, int battery, float screen){
            this(brand,model,battery,screen,0);
        }
    
        public Phone(String brand, String model, int battery, float screen, int pixels)
        {
            this.brand = brand;
            this.model = model;
            this.battery = battery;
            this.screen = screen;
            this.pixels = pixels;
        }
    }

    此时,客户端的代码是这样的:

        Phone phone1 = new Phone("Samsung","Note 7");
        Phone phone2 = new Phone("Apple","iphone6s",500,0,1000);

    这个构造器调用通常需要许多你本来不想设置的参数,但还是不得不为它们传递值。在上面的例子中,我们给screen传递了一个值为0。当然,如果只有这几个参数,看起来还好,但是随着参数数目的增加,问题很快就脱离了控制。
    总而言之:当参有许多参数的时候,客户端代码会很难编写,并且难以阅读。如果代码的阅读者想知道那些只是什么意思,必须很仔细地数着这些参数来探个究竟。一长串类型相同的参数会 导致一些微妙的错误。如果客户端不小心颠倒了两个参数的顺序,编译时不会报错,但是程序运行时会出现错误的行为。

    第二种方法是JavaBeans模式,在这种模式下,调用一个无参构造器来创建对象,然后调用setter方法来设置每个参数。例如:

    public class Phone{
        private String brand   ="";//品牌       required
        private String model;  =""//型号        required
        private int battery    = 0;//电池电量    optional
        private float screen   = 0;//屏幕尺寸    optional
        private int pixels     = 0;//像素       optional
    
        public Phone(){}
    
        public void setBrand(String brand) {
            this.brand = brand;
        }
        public void setModel(String model) {
            this.model = model;
        }
        public void setBattery(int battery) {
            this.battery = battery;
        }
        public void setScreen(float screen) {
            this.screen = screen;
        }
        public void setPixels(int pixels) {
            this.pixels = pixels;
        }
    }

    这种模式创建实例很容易,代码读起来也很容易。

        Phone phone = new Phone();
        phone.setBrand("Apple");
        phone.setModel("iphone6s");
        phone.setBattery(500);
        phone.setScreen(17.6);
        phone.setPixels(1000);

    JavaBeans模式阻止了把类做成不可变的可能。

    还有第三种方法。

    public class Phone {
        private final String brand;// 品牌
        private final String model;// 型号
        private final int battery;// 电池电量
        private final double screen;// 屏幕尺寸
        private final int pixels;// 像素
    
        public static class Builder {
            // Required parameters
            private final String brand;// 品牌
            private final String model;// 型号
    
            // Optional parameters
            private int battery = 0;// 电池电量
            private double screen = 0;// 屏幕尺寸
            private int pixels = 0;// 像素
    
            public Builder(String brand, String model) {
                this.brand = brand;
                this.model = model;
            }
    
            public Builder battery(int val) {
                battery = val;
                return this;
            }
    
            public Builder screen(double val) {
                screen = val;
                return this;
            }
    
            public Builder pixels(int val) {
                pixels = val;
                return this;
            }
    
            public Phone build() {
                return new Phone(this);
            }
        }
    
        private Phone(Builder builder) {
            brand = builder.brand;
            model = builder.model;
            battery = builder.battery;
            screen = builder.screen;
            pixels = builder.pixels;
        }
    }
    展开全文
  • fastapi-依赖注入

    2020-12-23 10:56:02
    依赖注入听起来好像很复杂,但是实际上炒鸡简单,一句话说就是:本来我接受各种参数来构造一个对象,现在只接受一个参数——已经实例化对象。 也就是说我对对象『依赖』是注入进来,而和它的构造方式解耦了。...

    如何用最简单的方式解释依赖注入?依赖注入是如何实现解耦的?
    FastApi学习-06
    fastapi(十六)-依赖关系
    fastapi教程-进阶九(Dependencies-1)

    什么是依赖注入

    依赖注入听起来好像很复杂,但是实际上炒鸡简单,一句话说就是:本来我接受各种参数来构造一个对象,现在只接受一个参数——已经实例化的对象。
    也就是说我对对象的『依赖』是注入进来的,而和它的构造方式解耦了。构造它这个『控制』操作也交给了第三方,也就是控制反转。
    不举抽象的什么造汽车或者小明玩儿手机的例子了。一个很实际的例子,比如我们要用 redis 实现一个远程列表。耦合成一坨的代码可以是这样写,其中我们需要自己构造需要用的组件:

    class RedisList:
        def __init__(self, host, port, password):
            self._client = redis.Redis(host, port, password)
    
        def push(self, key, val):
            self._client.lpush(key, val)
    
    l = RedisList(host, port, password)
    
    

    依赖翻转之后是这样的:

    class RedisList:
        def __init__(self, redis_client)
            self._client = redis_client
    
        def push(self, key, val):
            self._client.lpush(key, val)
    
    redis_client = get_redis_client(...)
    l = RedisList(redis_client)
    

    看起来好像也没什么区别,但是考虑下面这些因素:

    • 线下线上环境可能不一样,get_redis_client 函数在线上可能要做不少操作来读取到对应的配置,可能并不是不是一个简单的函数。
    • redis 这个类是一个基础组件,可能好多类都需要用到,每个类都去自己实例化吗?如果需要修改的话,每个类都要改。
    • 我们想依赖的是 redis 的 lpush 方法,而不是他的构造函数。

    所以把 redis 这个类的实例化由一个单一的函数来做是有意义的。

    fastapi中的依赖注入

    对于类A,要是实现A的功能,必须要类B的功能。所以在A中实例化一个B。一旦B需要重构,由于A几乎完全依赖与B,所以A几乎也要重构。这是一种相当耦合的模式依赖注入就是为了解决这种耦合性。
    A不再new一个B的实例,而是让B的一个实例作为A的一个成员存在,A不再关注B的实例化,只关注B的方法。(这是我的理解,也许有不对的地方)

    在FastApi的框架中,依赖注入用于解决重复的逻辑代码,分享数据库的链接,统一验权等功能。旨在减少代码重复。

    async def pagination(page_num: int = 1, page_count: int = 10):
        return {"page_num": page_num, "page_count": page_count}
     
    @app.get("/request01")
    async def request01(*, page: dict = Depends(pagination), c: int):
        return [page, c]
    

    使用Depends实现依赖注入,pagination方法接收的page_num当前页码数,page_count每页的数据量,经过处理后返回给page一个起始结束下标的范围字典。在这个例子中来看,和其实现的功能和装饰器有点像,对于request01,不关注我接受了什么数据,只希望获取分页的下标范围,而pagination方法实现了该功能,这样当分页的数据格式发生变更时,也只需要改变pagination方法。

    展开全文
  • 介绍 分离复杂对象构建和表示...我们要生产一台小米手机,并且规定手机的尺寸,重量,品牌这些属性,最后利用Build进行生产,首先看一下类图: 一、首先定义Phone抽象类以及具体实现: public abstract class Ph...

    介绍

    分离复杂对象的构建和表示,同样的构建过程可以创建不同的表示。当初始化一个对象特别复杂,如使用多个构造方法,或者说有很多参数(例如100个参数),并且都有默认值时,可以使用此模式。

    实例演示

    我们要生产一台小米手机,并且规定手机的尺寸,重量,品牌这些属性,最后利用Build进行生产,首先看一下类图:
    在这里插入图片描述
    一、首先定义Phone抽象类以及具体实现:

    public abstract class Phone {
        double size;
        double weight;
        String brand;
    
        public void setSize(Double size){
            this.size = size;
        }
    
        public void setWeight(Double weight){
            this.weight = weight;
        }
    
        public abstract void setBrand(String brand);
    
        @Override
        public String toString() {
            return "Phone{" +
                    "size=" + size +
                    ", weight=" + weight +
                    ", brand='" + brand + '\'' +
                    '}';
        }
    }
    
    public class MiPhone extends Phone {
        @Override
        public void setBrand(String brand) {
            this.brand = brand;
        }
    }
    

    二、定义build抽象类以及具体实现:

    public abstract class Builder {
        abstract Builder buildSize(double size);
        abstract Builder buildWeight(double weight);
        abstract Builder buildBrand(String brand);
        abstract Phone build();
    }
    

    返回值为Builder类型是为了能够连续的调用函数。

    public class MiPhoneBuilder extends Builder {
        Phone phone = new MiPhone();
    
        @Override
        Builder buildSize(double size) {
            phone.setSize(size);
            return this;
        }
    
        @Override
        Builder buildWeight(double weight) {
            phone.setWeight(weight);
            return this;
        }
    
        @Override
        Builder buildBrand(String brand) {
            phone.setBrand(brand);
            return this;
        }
    
        @Override
        Phone build() {
            return phone;
        }
    }
    

    三、最后在Main方法中进行调用:

    public class Main {
        public static void main(String[] args) {
            Builder builder = new MiPhoneBuilder();
            Phone phone = builder.buildSize(6.5).buildWeight(500.0).buildBrand("XiaoMi").build();
            System.out.println(phone.toString());
        }
    }
    
    Phone{size=6.5, weight=500.0, brand='XiaoMi'}
    

    总结

    为了灵活构造复杂对象,该对象会有多个成员变量,在外部调用的时候,不需要或者不方便一次性创建出所有的成员变量,在这种情况下,使用多个构造方法去构建对象,很难维护,这时候Builder设计模式解决这个问题。

    展开全文
  • 建造者模式

    2015-09-01 11:03:45
     它们都是创建复杂对象设计模式,区别在于Builder建造者模式着重于分步骤构建一个复杂对象(比如手机的各种套餐),而abstract factory 抽象工厂模式则着重于多个系列产品对象(即对象组)的构造。建造者模式...
  • JAVA基础--类与对象

    2019-03-12 12:19:19
    面对对象是一种程序设计的思想,他把复杂的事情简单化,面对对象重要的两个概念便是:类与对象 2.类 类,就像是构造对象的一份蓝图,就好像一部手机生产之前他是有一个设计参数图,这就相当于一个类,然后通过工厂生产...
  • blaster-源码

    2021-03-14 10:16:53
    我没有使用任何现有渲染引擎,因为无知地盯着黑屏是我喜欢消磨时间方式。 另外,我想了解事物运作方式。 我试图使minigl尽可能简单。 原因之一是我尚不知道如何使它变得整洁和复杂,其二是它使代码更加...
  • C#微软培训教材(高清PDF)

    千次下载 热门讨论 2009-07-30 08:51:17
    10.3 构造函数和析构函数 .119 10.4 小 结 .122 第十一章 方 法 .124 11.1 方法声明.124 11.2 方法中参数.125 11.3 静态和非静态方法.129 11.4 方法重载.130 11.5 操作符重载.134 11.6 小 ...
  • C#微软培训资料

    2014-01-22 14:10:17
    10.3 构造函数和析构函数 .119 10.4 小 结 .122 第十一章 方 法 .124 11.1 方法声明.124 11.2 方法中参数.125 11.3 静态和非静态方法.129 11.4 方法重载.130 11.5 操作符重载.134 11.6 小 ...
  • 软件工程教程

    热门讨论 2012-07-06 23:10:29
    在较大公司,为自有品牌或者其他品牌设计手机或者平板电脑总体方案。 根据需求对系统进行定制外,为系统编写定制应用。 第二类开发者 在创业型公司或者是独立开发者,盈利方式主要2种: 为国外公司外包开发,...
  • Android 上百实例源码分析以及开源分析 集合打包4

    千次下载 热门讨论 2012-07-10 21:54:03
    它基本上执行主要业务:定期更新的DF的手机中所有接触的位置(由模拟的GPS更新)。 GeoNavigator 自定义导航类,启动或关闭联络位置的更新。 GuiEventHandler UI处理类。 IEventHandler 事件处理类接口。 ...
  • 正则表达式

    2014-12-03 14:51:39
    这些复杂的模式使用的正则表达式语法指定了该表达式中每个元素要重复出现的次数. 指定复制的字符总是出现在它们所作用的模式后面.由于某种复制类型相当常用.所以有一些特殊的字符专门用于表示它们.例如: +号匹配的...
  • 所以在进行DFT运算时会不断调用类的构造函数与析构函数,这导致了进行DFT运算使用时间比Matlab写出来要慢很多。 虽然处理起来时间比较长,但是相比FFT优势是可以对非2幂数大小图片进行傅里叶变换,而非2...
  • 模型仅给出粗糙的正向、负向情感划分,可以构造复杂的模型来检测更细粒度的情感。 未对参数作很多尝试,没有采用交叉验证,没有进行长时间训练,否则模型精度可能有进一步提高 感谢 感谢你读完这个长长的README...
  • 1.3 协议间交互作用的复杂性 1 1.4 本书采用方法 2 1.5 研究代码重要性 2 1.6 Xinu操作系统 2 1.7 本书其余部分组织 3 1.8 小结 3 深入研究 4 第2章 操作系统中TCP/IP软件结构 5 2.1 引言 5 2.2 ...
  • 其中包含 PPT, DWR JQUERY 及 多套资料文档 AJAX学习 作者:高伟 ...•缺点:太过复杂,整个界面的构造过于复杂。 AJAX会有怎样未来? •AJAX会有怎样未来? ……………………. AJAX学习交流结束啦!
  • 尹成Python27天入门到项目实战

    千人学习 2020-12-05 17:04:22
    预编译概念搜索技能搜索用在找出第一个邮箱手机提取findall字符串切割筛选正则表达式正则表达式替换单个字符判断中括号选择一个字符正则表达式次数正则开头结尾括号与选择正则表达式特殊符号day19down 递归与爬虫...
  • 同时也没提供一种结构化方式去构造动态应用程序。 静态网站是受搜索引擎欢迎网站,因为它相对固定,所以网站 <em>SEO</em> 非常好做,我猜测这也是为什么现在文档网站大部分都是静态网页...
  • 大话数据结构

    2018-12-14 16:02:18
    现实中,人与人之间关系就非常复杂,比如我认识朋友,可能他们之间也互相认识,这就不是简单一对一、一对多关系了,那就是我们今天要研究主题——图。 7.2.1各种图定义 214 7.2.2图顶点与边间关系 217...

空空如也

空空如也

1 2
收藏数 40
精华内容 16
关键字:

构造最复杂的手机