当前位置: 首页 > 编程日记 > 正文

工厂模式(Factory)(转)

先来明确一个问题,那就是有的时候,实例化这个活动不应该总是公开的进行,

也就是不要公开的使用 new 操作符,因为,这样容易造成耦合问题。

我们不应该针对实现编程,但是当我们在使用 new 的时候,便是针对实现编程,

而如果您要实例化的话,必须要使用 new 这个关键字,

很明显,这是一个矛盾问题!!!

当然这里的矛盾并不是说不能够使用 new ,而是更好的使用了 new。

那么如何来解决这样一个矛盾问题呢?

先来看一副类图

image

上面这副类图反映的就是一个简单工厂模式了,确切的说,简单工厂不能说是一种设计模式,

其更可以被称作是一种编程习惯,因为我们习惯性的将一些类的实例化放到另外一个类中来完成。

这样在代码的可读性上有很大的帮助,

上面的类图反映的就是将一组相似对象(继承自同一个类)的实例的创建放到另外一个对象中完成,

即通过 ProductFactory 这个类来按需创建对象,何为按需创建对象呢(或者说是动态创建对象)?

这就是要求在客户端传入一个参数给 ProductFactory ,

然后 ProductFactory 根据这个参数来创建指定的对象实例并返回。

下面通过一个 Demo 来将上面的简单工厂进行实现

image

下面就来看上面的这个水果例子的具体实现了

首先要有一个 Fruit 的抽象类

namespace SimpleFactory
{
    public abstract class Fruit
    {
        /// <summary>
        /// 在此仅代表性的定义一个方法
        /// </summary>

        public abstract void Display();
    }
}

然后就是继承自 Fruit 抽象类的四个子类

using System;

namespace SimpleFactory
{
    class
Apple : Fruit
    {
        public override void Display()
        {
            Console.WriteLine("我的名字是:苹果 ,主要特性为养颜护肤");
        }
    }
}

using System;

namespace SimpleFactory
{
    class
Orange:Fruit
    {

        public override void Display()
        {
            Console.WriteLine("我的名字是:橘子 ,主要特性为滋肝润胃");
        }
    }
}

using System;

namespace SimpleFactory
{
    class
Pear:Fruit
    {
        public override void Display()
        {
            Console.WriteLine("我的名字是:梨子 ,主要特性为滋肝润胃");
        }
    }
}

using System;

namespace SimpleFactory
{
    class Banana:Fruit
    {
        public override void Display()
        {
            Console.WriteLine("我的名字是:香蕉 ,主要特性为滋肝润胃");
        }
    }

}

最后还有一个非常重要的类,那就是工厂类,即 FruitFactory

using System;

namespace SimpleFactory
{
    public class FruitFactory
    {
        public FruitFactory()
        {
        }

        /// <summary>
        /// 简单工厂中必须要有一个方法来根据指定的逻辑创建实例
        /// </summary>
        /// <param name="fruitType"></param>
        /// <returns></returns>

        public static Fruit CreateFruit(string fruitType)
        {
            if (!String.IsNullOrEmpty(fruitType))
            {
                switch (fruitType)
                {
                    case "Apple":
                        return
new Apple();
                    case "Orange":
                        return
new Orange();
                    case "Pear":
                        return
new Pear();
                    case "Banana":
                        return new Banana();
                }
            }
            return null;
        }
    }
}

最后就是来看客户端代码和运行结果了

using System;
using SimpleFactory;

namespace SimpleFactoryTest
{
    class Program
    {
        static void Main(string[] args)
        {
            //创建一个苹果实例
            //并且调用这个实例的 Display 方法

            FruitFactory.CreateFruit("Apple").Display();

            //创建一个橘子实例
            //并且调用这个实例的 Display 方法

            FruitFactory.CreateFruit("Orange").Display();

            //创建一个梨子实例
            //并且调用这个实例的 Display 方法

            FruitFactory.CreateFruit("Pear").Display();

            Console.ReadLine();
        }
    }
}

image

上面写的这个 Demo 呢,是典型的简单工厂了,

通过简单工厂呢,我们实现了对实例化这个活动的封装,

因为把所有的实例化全部放入了另外一个对象(也就是工厂)中,

同时实现了针对接口编程,而非实现,在上面的 Demo 中,这里体现在了工厂 FruitFactory 中,

我们通过多态来实现了针对接口 Fruit 编程,而非针对具体类,如 Apple 这些来编程。

这样,使用简单工厂便轻松的解决了一开始提出的矛盾问题。

总结一下简单工厂的优点:

简单工厂的工厂类中包含了必要的逻辑判断,这样就可以根据客户端的选择条件来动态的实例化相关的类,

对于客户端来说,其去除了与具体产品(比如 Apple)之间的依赖。

当然简单工厂模式是有缺点的:

最为明显的就是,其违背了开-闭原则,

在上面的 Demo 中,如果我要再增加一种水果---葡萄(Grape),

那么做法如下,首先是定义一个葡萄类 Grape,让其继承自 Fruit ,然后呢,您还必须修改工厂类,

因为您必须在工厂类的 switch 中添加几句代码

case "Grape":
    return new Grape();

这样就非常明显了,因为您已经对 FruitFactory 类进行了修改,

且这个修改是必须得,否则您就无法增加葡萄这种水果。

所以,简单工厂是明显的违背了开-闭原则的。

由于简单工厂违背了开-闭原则,所以还必须在其上面改进一下,这样可以得出下面要谈的模式,

也就是工厂方法模式(Factory Method)

先来给出工厂方法的结构图吧

image

上面的类图稍微简单了点,但是还是可以反映出一些内容的,

和简单工厂相比的话,在工厂方法中,创建对象将不会在集中在一个类中了,

而是通过一个 FactoryMethod 方法在各个子类中实现对象的实例化,

这句话怎么理解呢?

也就是,在上面的类图中,

创建 ConcreteProduct 类的实例这个功能被封装在了 ConcreteProductFactory 中,

而不是在 ProductFactory 中了,

下面再看一副稍微复杂点的类图或许能够帮助更好的理解

image

这一副类图呢,更好的展现出了工厂方法的基本实现原理,

每一个具体产品类都有与其相对应的具体工厂类,而这个具体工厂类呢,

其唯一职责就是创建与其对应的具体产品类的实例。

比如 ConcreteProductFactoryA 依赖于 ConcreteProductA ,也就是只创建 ConcreteProductA 实例。

在这里还是先给出工厂方法的定义吧

工厂方法模式,定义了一个用于创建对象的接口,让子类来决定要实例化哪一个类,

工厂方法让类把实例化延迟到其子类。

下面呢,在来看一个实际的 Demo ,这个 Demo 还是延续前面介绍简单工厂时的水果的例子

先来看类图吧

image

从上面的类图中可以看到,拥有一个水果抽象类 Fruit

然后是四个水果具体类,还有一个水果工厂抽象类 FruitFactory ,

然后是四个具体工厂类,分别用来创建四个水果具体类的实例。

下面就来看代码啦

先是 Fruit 抽象类

namespace FactoryMethod
{
    public abstract class Fruit
    {
        public abstract void Display();
    }
}

然后是四个具体的水果类

using System;

namespace FactoryMethod
{
    class Apple:Fruit
    {
        public override void Display()
        {
            Console.WriteLine("我的名字是:苹果 ,主要特性为养颜护肤");
        }
    }
}

using System;

namespace FactoryMethod
{
    class Banana:Fruit
    {
        public override void Display()
        {
            Console.WriteLine("我的名字是:香蕉 ,主要特性为滋肝润胃");
        }
    }
}

using System;

namespace FactoryMethod
{
    class Orange : Fruit
    {
        public override void Display()
        {
            Console.WriteLine("我的名字是:橘子 ,主要特性为滋肝润胃");
        }
    }
}

using System;

namespace FactoryMethod
{
    class Pear : Fruit
    {
        public override void Display()
        {
            Console.WriteLine("我的名字是:梨子 ,主要特性为滋肝润胃");
        }
    }
}

再来看抽象工厂类 FruitFactory

namespace FactoryMethod
{
    public abstract class FruitFactory
    {
        public abstract Fruit GetFruit();
    }
}

然后就是四个具体工厂类

namespace FactoryMethod
{
    public class
AppleFactory:FruitFactory
    {
        public override
Fruit GetFruit()
        {
            return new Apple();
        }
    }
}

namespace FactoryMethod
{
    public class
BananaFactory : FruitFactory
    {
        public override
Fruit GetFruit()
        {
            return new Banana();
        }
    }
}

namespace FactoryMethod
{
    public class
OrangeFactory : FruitFactory
    {
        public override
Fruit GetFruit()
        {
            return new Orange();
        }
    }
}

namespace FactoryMethod
{
    public class
PearFactory : FruitFactory
    {
        public override Fruit GetFruit()
        {
            return new Pear();
        }
    }
}

所有的类的结构的代码就在上面了,下面将要看的就是客户端代码和效果了

using System;
using FactoryMethod;

namespace FactoryMethodTest
{
    class Program
    {
        static void Main(string[] args)
        {
            FruitFactory factory;
            Fruit fruit;

            //首先要实例化一个苹果工厂
            factory = new AppleFactory();
            //然后通过工厂来获得苹果类对象
            fruit = factory.GetFruit();
            //访问苹果类对象
            fruit.Display();

            //首先要实例化一个梨子工厂
            factory = new PearFactory();
          
//然后通过工厂来获得梨子类对象
            fruit = factory.GetFruit();
           //访问梨子类对象
            fruit.Display();

            Console.ReadLine();
        }
    }
}

image

上面呢,就是关于工厂方法模式的 Demo 的完整演示了,

下面将通过比较简单工厂和工厂方法这两种设计模式来体现出各自的优劣之处:

简单工厂把全部的事情,在一个地方(类)全部处理完,而工厂方法却不同,

其是通过创建一个框架(FruitFactory),

然后让子类(AppleFactory 等)决定要如何实现,简单工厂呢,其将对象的创建封装起来了,

但是其违背开-闭原则,弹性太弱,正如前面介绍简单工厂时,提到的加入一种水果葡萄时会造成修改类,

而工厂方法则恰恰解决了简单工厂的这一毛病,其通过将实例化延迟到子类成功解决了简单工厂的这一问题,

其实呢,可以这样去理解,简单工厂在其主要的工厂方法中,存在了逻辑判断语言,

这是因为,工厂方法必须根据外界给出的条件来创建符合要求的实例,

而工厂方法却不存在这一点,也就是不需要指到外界的情况,

这是为何呢?其实这是因为,工厂方法将这些本来应该存在的判断逻辑移到了客户端代码中,

(通过客户的需求来选择生成那一种水果实例,比如我的演示中生成的就是苹果和梨子这两种实例)

这样的话,可以解决掉简单工厂违背开-闭原则这一毛病,

比如,要在上面的 Demo 中再添加一种水果 Grape 的话,

使用工厂方法的话,您只需要添加一个 Grape 类,让其继承自 Fruit ,

然后再为其添加一个 GrapeFactory 类,让这个类继承自 FruitFactory 类就 OK 了,

其余的代码便是在客户端来完成了。

下面将要介绍的是抽象工厂模式(Abstract Factory)

先来看抽象工厂的大体的结构图

image

要想明白上面的这幅类图的话,先必须要明确一个概念,

产品族:

在上面的产品列表中呢,有两个产品族,一个是“具体产品A--1”和”具体产品B--1“组成的一个族,

还有一个是“具体产品A--2”和“具体产品B--2”组成的一个族。

产品族就是在不同产品等级结构中,功能相关联的产品组成的家族。

下面就来介绍抽象工厂了(有些内容生涩的话,可以看完 Demo 后回过头来浏览)

下面给出的是抽象工厂的定义:

提供一个创建一系列相关或者是相互依赖对象的接口,而无需指定它们具体的类。

再来看衣服详细的类图

image

其实从上面这副类图中可以看出,每一个具体的工厂,它都只负责创建一个产品族中的产品的实例,

从抽象工厂中派生出的具体工厂,这些具体工厂产生相同的产品(这些产品都继承自同一父类),

比如,ConcreteFactory1 和 ConcreteFactory2 中的 CreateProductA 这个方法都是产生 AbstractProductA 这种类型的产品,

但是产品的实现却是不同的,比如 ConcreteFactory1 中的 CreateProductA 实现的是产生一个 ConcreteProductA—1 产品,

而 ConcreteFactory2 中的 CreateProductA 实现的是产生一个 ConcreteProductA—2 产品,

总的来说就是不同的具体工厂产生不同的产品族,

而抽象工厂则是定义一个负责创建一组产品(也就是一个产品族)的接口,

比如上面的类图中只存在两个产品族,所以在抽象工厂中便只需要定义两个接口就可以了。

下面来剖析一下抽象工厂的优点和缺点

抽象工厂的最大好处在于交换产品系列非常方便,由于具体工厂类在一个应用中只需要在初始化的时候出现一次,

这样就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置,

比如,我在应用中本来使用的是工厂 ConcreteFactory1 来生成的产品族 1 ,

而现在需求改变了,不再使用产品族 1 ,而必须使用产品族 2 时,

此时,只需要在客户端代码中初始化 ConcreteFactory1 的位置,

把 ConcreteFactory1 改为 ConcreteFactory2 就可以了,这样就成功的将产品族1 切换到了使用产品族2 上面来,

其次,抽象工厂让具体的创建实例过程与客户端分离,客户端是通过他们的抽象接口操纵实例,

产品的具体类名也被具体工厂的实现分类,不会出现在客户端代码中。

这一点上的话,简单工厂和工厂方法也做得很不错,即依赖于抽象。

同时,如果需求需要扩展的话,比如,要重新增加一个产品族,这也很好办,

只需要增加一个具体工厂,然后增加产品族就可以了,

总之是,抽象工厂很好的遵循了开--闭原则和依赖倒置原则。

下面就来看一个 Demo ,从这个 Demo 中看出抽象工厂的优点

先来展现一下具体的类图

image

上面的类图呢,说明的是有两个具体工厂,一个是 Linux 控件的制造,还有一个是 Windows 控件的制造,

然后,有两个产品族,一个是 WindowsTextBox 和 LinuxTextBox 组成的 TextBox 产品族,

还有一个就是 WindowsButton 和 LinuxButton 组成的 Button 产品族。

下面就来写类了

先来看工厂类吧

namespace AbstractFactory
{
    public abstract class
AbstractFactory
    {
       
//在抽象工厂中,应该包含所有产品创建的抽象方法
 
       public abstract Button CreateButton();
        public abstract TextBox CreateTextBox();

    }
}

namespace AbstractFactory
{
    public class WindowsFactory:AbstractFactory
    {
        public override Button CreateButton()
        {
            return
new WindowsButton();
        }

        public override TextBox CreateTextBox()
        {
            return
new WindowsTextBox();
        }
    }
}

namespace AbstractFactory
{
    public class LinuxFactory:AbstractFactory
    {
        public override Button CreateButton()
        {
            return
new LinuxButton();
        }

        public override TextBox CreateTextBox()
        {
            return
new LinuxTextBox();
        }
    }
}

下面就给出所有的产品类

namespace AbstractFactory
{
    public abstract class
Button
    {
        public abstract void DisplayButton();
    }
}

using System;

namespace AbstractFactory
{
    class LinuxButton:Button
    {
        public override void DisplayButton()
        {
            Console.WriteLine("我的类型是:{0}",
                this.GetType().ToString());
        }
    }
}

using System;

namespace AbstractFactory
{
    class WindowsButton : Button
    {
        public override void DisplayButton()
        {
            Console.WriteLine("我的类型是:{0}",
                this.GetType().ToString());
        }
    }
}

namespace AbstractFactory
{
    public abstract class TextBox
    {
        public abstract void DisplayTextBox();
    }
}

using System;

namespace AbstractFactory
{
    class
LinuxTextBox : TextBox
    {
        public override void DisplayTextBox()
        {
            Console.WriteLine("我的类型是:{0}",
                this.GetType().ToString());
        }
    }
}

using System;

namespace AbstractFactory
{
    class
WindowsTextBox:TextBox
    {
        public override void DisplayTextBox()
        {
            Console.WriteLine("我的类型是:{0}",
                this.GetType().ToString());
        }
    }
}

上面就是整个 Demo 的类了,下面就是看一下 Main 函数和效果了

using System;
using AbstractFactory;

namespace AbstractFactoryTest
{
    class Program
    {
        static void Main(string[] args)
        {
            AbstractFactory.AbstractFactory factory;
            Button button;
            TextBox textBox;

           //Windows 下操作
            factory = new WindowsFactory();
            button = factory.CreateButton();
            textBox = factory.CreateTextBox();
            button.DisplayButton();
            textBox.DisplayTextBox();

            Console.WriteLine();

            //Linux 下操作
            factory = new LinuxFactory();
            button = factory.CreateButton();
            textBox = factory.CreateTextBox();
            button.DisplayButton();
            textBox.DisplayTextBox();

            Console.ReadLine();
        }
    }
}

image

从上面 Main 函数来看的话,如果你的系统本来是基于 Linux 的话,你只需更改一行代码

factory = new WindowsFactory();
即可实现将系统更改为 Windows ,

抽象工厂在这种情况下是非常有用的,比如,如果要实现后台数据库从 Oracle 转换到 Sql Server,

则采用抽象工厂的思想实现是最好的。

下面总结一下抽象工厂的优缺点

首先,抽象工厂的话,其可以更加方便的实现交换一个产品系列,

就像上面的 Demo 中可以轻易的实现从 Linux 上转换为 Windows,

同时,客户端代码中依赖的是抽象,而非具体的实现,

但是,抽象工厂也是有缺点的,其实这个缺点也很明显,那就是显得过于臃肿,

上面的 Demo 尽管还只有两个产品族,类图就显得有些难看了,

如果产品族一多的话,那么总的类数是成几倍的增加,这样使整个结构变得过于复杂,

类的结构也会变得更为庞大。

尾声

上面呢,接连介绍了简单工厂,工厂方法,抽象工厂,

整个工厂模式的介绍就到此告一段落了。


转载于:https://www.cnblogs.com/silencExplode/archive/2012/01/29/2331225.html

相关文章:

Asp.net后台创建HTML

为了使HTML界面中的内容能根据数据库中的内容动态显示用户需要的内容&#xff0c;或者根据权限不同要显示同而实现页面内容的动态创建 使用HtmlGenericControl创建HTML标签 引入命名空间: using System.Web.UI.HtmlControls; 更改其属性: hgg_div.Attributes.Add("style&q…

oracle视图(转)

视图的概念 视图是基于一张表或多张表或另外一个视图的逻辑表。视图不同于表&#xff0c;视图本身不包含任何数据。表是实际独立存在的实体&#xff0c;是用于存储数据的基本结构。而视图只是一种定义&#xff0c;对应一个查询语句。视图的数据都来自于某些表&#xff0c;这些…

Redis 事物

redis 事物&#xff1a; Redis 事物的实现&#xff1a; 首先 wath监控键值 myKey开启批量执行 multi&#xff0c;执行命令入列&#xff0c;执行 exec 。如果监控的键值mykey 没有被修改过&#xff0c;则exec 中批量执行的命令成功&#xff0c;否则执行失败。无论执行成功与否&a…

python dos攻击_利用SMB漏洞DoS攻击任何Windows系统

原标题&#xff1a;利用SMB漏洞DoS攻击任何Windows系统近日微软报出SMB V1存在漏洞&#xff0c;安全研究员并将此漏洞称作 “ SMBLoris ”&#xff0c;解释其能够发动拒绝服务&#xff08;Dos&#xff09;攻击&#xff0c;可以感染 Windows 2000 及以上操作系统的任一版本 SMB …

java基础编程题(2)

1、给定一个二叉树&#xff0c;找出其最大深度。 注&#xff1a;二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode(int x…

python元组转字典_python中怎么将元组、字典转化为列表

python中将元组、字典转化为列表的方法&#xff1a; python中可以使用list()方法将元组或字典转化为列表&#xff1a; list()方法语法&#xff1a;list( tup ) 参数 tup -- 要转换为列表的元组。 返回值 返回列表。 示例&#xff1a; 将元组转换为列表&#xff1a;#!/usr/bin/p…

搭建Git服务器教程转载

1. 在Windows下使用sshmsysgit客户端搭建Git服务器 http://www.codeproject.com/Articles/296398/Step-by-Step-Setup-Git-Server-on-Windows-with-CopS 2. 在Windows下使用Apachemsysgit客户端搭建Git服务器 http://www.devbean.info/2011/10/apache-git-server-on-windows/ 3…

存储过程处理错误数据

create or replace procedure ERR_REDUCEDATA is --sx --定义变量 v_realindiobjid VARCHAR2(100); v_indiobjid VARCHAR2(32); v_residuemoney number ; v_reducemoney number ; v_approbjid VARCHAR2(32); -- v_indiecoid VARCHAR2(32); --v_indiecocode VARCHAR2(32); v_Ap…

[置顶] 面向业务开发应用

自从计算机出现后&#xff0c;快速便捷的从太平洋一样的文海中找到水滴大小的资料真正成为了可能&#xff0c;而能够帮助人们实现这一愿望的程序员就像中世纪的航海家一样用神秘的代码程序指引着计算机一步一步实现的需求。而他们所用的被称之为“程序”的序列组合&#xff0c;…

vector方法

借鉴网上资料&#xff0c;整理了vector使用的一些方法&#xff0c;记录下来&#xff0c;方便以后查阅 vector初始化 vector<int>a(10) //只定义长度 vector<int>a(10,1)//长度为10&#xff0c;初始值为1 vector<int>a(b); //用b向量来创建a向量&#xff0c;…

MyEclipse Enterprise Workbench 9.0 破解及注册机 注册码

MyEclipse 9.0的激活机制终于破解了&#xff0c;破解步骤比老版本要复杂一些&#xff0c;但是是绝对可以破解的&#xff0c;这个破解对主程序无任何修改&#xff0c;只替换公钥&#xff0c;如果有牛人会快速从公钥反推私钥&#xff0c;那就什么都不用改了&#xff0c;步骤如下&…

python字典一键多值_python字典中如何一键多值的写入?

python字典中如何一键多值的写入&#xff1f; python字典中一键多值写入的方法&#xff1a; 1、循环写入字典key、value、删除指定的键值对&#xff1a; 原文本‘jp_url.txt’每行元素以逗号分隔:host_key,product_id,product_name,cont_start,cont_end ah2.zhangyue.com,10000…

向实现细节低头

本来想搞明白所有的东西&#xff0c;然后自己集成&#xff0c;避免引入额外的组件&#xff0c;避免复杂的维护成本。 现在想想&#xff0c;相比于投入的巨大精力&#xff0c;其收益过小&#xff0c;还是要有所取舍。转载于:https://www.cnblogs.com/youge-OneSQL/p/9268924.htm…

Session丢值的问题

本来本地调试好好的,一上服务器session就非常容易丢失,表现在,用window.href跳转丢session,用httpmoulde丢session,在frame里面ifarme里面丢session,折磨了一天,才知道是因为应用程序池的原因,一个池里面放了太多网站,导致session丢失(系统还没有上线,光放那也不行), 还有应用程…

换发型app任性扣费?苹果app订阅任性扣费?怎么办?刚成功

2019年9月18日17:09:27 什么黑猫举报没用 先关闭订阅 账户中心自助申请试试&#xff0c;不通过再进行下面这步 https://getsupport.apple.com/?callerhome&PRKEYS 技术支持网址 然后就等电话吧&#xff0c;一般10秒钟就打过来了。 告诉原因&#xff0c;提供收费的订单号&a…

用eclipse阅读编辑android和kernel,uboot的源代码

from: http://hi.baidu.com/designhouse/blog/item/ff3f0df4a33571f37709d736.html 1. 用eclipse阅读编辑android源代码的配置方法有官方文档&#xff0c;非常详细&#xff0c;http://source.android.com/source/using-eclipse.html 阅读android代码用的是Eclipse IDE for Jav…

当一个序列满足对于任意的前 项和都满足不小于_时间序列分析第01讲--平稳序列(基本概念,线性平稳序列)...

第一章 平稳序列1.1平稳序列基本概念无论是从原序列中把趋势项去掉得到的随机波动项&#xff0c;还是用随机差分后得到残差序列&#xff0c;都会存在一种现象&#xff1a;随机项会沿着水平值波动&#xff0c;并且前后之间具有相关性&#xff0c;与独立序列不同。一、定义定义1.…

京医通如何删除临时卡,解绑

1、解绑的话&#xff0c;如果你是正式卡或者社保卡&#xff0c;可以在账户里面&#xff0c;点击卡进去详情页&#xff0c;里面会有一个解绑 2、重点就是临时卡了&#xff0c;挂号的时候很恶心。 目前唯一的解决办法就是&#xff0c;注销账户。 1&#xff09;、解绑所有正式卡 2…

T-SQL查询——详解公用表达式(CTE)

对于Select查询语句来说&#xff0c;通常情况下&#xff0c;为了是T-SQL代码更加简洁和刻度&#xff0c;在一个查询中应用另外的结果集都是通过视图而不是查询进行分解的&#xff0c;但是&#xff0c;视图作为系统对象存储在数据库中&#xff0c;那对于结果集仅仅需要在存储过程…

如何实现显示超过10个字符就显示省略号?

// 要展示的文本(nickName) this.nickName 风一样的女子凤一样的我&#xff0c;有想认识嘛~~ if (this.nickName.length > 10) {this.nickName this.nickName.substring(0, 10) "...";console.log(00, this.nickName)}备注&#xff1a;substring() 方法用于提取…

课程实验代码及动手动脑测试

枚举类型测试代码&#xff1a; public class EnumTest {public static void main(String[] args) {Size s Size.SMALL;Size t Size.LARGE;// s和t引用同一个对象&#xff1f;System.out.println(s t); //// 是原始数据类型吗&#xff1f;System.out.println(s.getClass().is…

python利用自动识别写模块_Python 利用pytesser模块识别图像文字

使用的是python的pytesser模块&#xff0c;原先想做的是图片中文识别&#xff0c;搞了一段时间了&#xff0c;在中文的识别上还是有很多问题&#xff0c;这里做记录分享。 可将图片中的文字转换成文本&#xff08;主要是英文&#xff09;。 1.pytesser安装 使用设备&#xff1a…

C02-程序设计基础提高班(C++)第9周上机任务-类和对象

第9周&#xff1a;阅读教材第8章&#xff08;p231-262&#xff09;&#xff0c;主要内容是类和对象&#xff0c;学会定义类和对象解决问题&#xff0c;完成第9周上机任务&#xff1b;(回到C02-程序设计基础提高班&#xff08;C&#xff09;学习安排)实践任务&#xff1a;【任务…

在不影响配置下,清除netscreen密码

在缺省情况下&#xff0c;设备恢复特征被启用。可通过输入 unset admin device-reset 命令禁用它。同样&#xff0c;如果NetScreen 设备处于 FIPS 模式&#xff0c;恢复特征被自动禁用。1. 在登录提示下&#xff0c;键入设备的序列号。2. 在密码提示下&#xff0c;再次键入序列…

如何删除一个CSDN上自己上传的资源

如何删除一个CSDN上自己上传的资源 第一步&#xff0c;找到你想删除的资源&#xff0c;其URL举例为&#xff1a;http://download.csdn.net/detail/ssergsw/9733040则删除的get请求为&#xff1a;http://download.csdn.net/index.php/user_console/del_my_source/9733040删除成功…

关于计算机中二进制原码,反码,补码的简要解释

原码&#xff0c;补码&#xff0c;反码的概念 正数原码&#xff1a;正数的原码为取绝对值的数转二进制&#xff0c;5的原码为 00000000 00000000 00000000 00000101 负数原码&#xff1a;负数的原码为取绝对值的数转二进制&#xff0c;然后符号位&#xff08;最高位&a…

python是一种面向对象的高级语言_爬了世纪佳缘后发现了一个秘密,世纪佳缘找对象靠谱吗?...

今天在知乎上看到一个关于【世纪佳缘找对象靠谱吗&#xff1f;】的讨论&#xff0c;其中关注的人有 1903&#xff0c;被浏览了 1940753 次&#xff0c;355 个回答中大多数都是不靠谱。用 Python 爬取世纪佳缘的数据是否能证明它的不靠谱&#xff1f;数据抓取 在 PC 端打开世纪佳…

使用邮件规则,将收到的邮件进行分类

随着工作的进行&#xff0c;我们经常会发现邮箱里一大堆各种各样的邮件&#xff0c;而要从中找到指定类型的邮件&#xff0c;只能每次都进行一次搜索。但是&#xff0c;经常这样搜索&#xff0c;先不说效率如何&#xff0c;它肯定会对我们的工作进行一些影响。 在这里&#xff…

多个CALayer的联动

在如何通过手势捕获CALayer基础上做了个示例&#xff0c;两个CALayer的联动&#xff0c;当拖动左侧的Layer的时候&#xff0c;右侧的Layer随动。因为右侧的动画没有关闭&#xff0c;有延迟&#xff0c;产生随动的效果。如果不想延迟&#xff0c;可参考拖动动画的问题及解决。 在…