观察者模式用于描述对象之间的依赖关系,它引入了观察者和观察目标两类不同的角色,由于提供了抽象层,它使得增加新的观察者和观察目标都很方便。观察者模式广泛应用于各种编程语言的事件处理模型中,Java语言也提供了对观察者模式的全面支持。
抽象目标类
public abstract class Subject {
protected ArrayList observers<Observer> = new ArrayList();
public void attach(Observer observer) {
observers.add(observer);
}
public void detach(Observer observer) {
observers.remove(observer);
}
public abstract void notify( );
}
具体目标类
public class ConcreteSubject extends Subject {
//实现通知方法
public void notify() {
for(Object obs:observers) {
((Observer)obs).update();
}
}
}
抽象观察者类
public interface Observer {
public void update();
}
具体观察者类
public class ConcreteObserver implements Observer {
public void update() {
……
}
}
股票
抽象目标类:股票
public interface Stocks {
ArrayList<Observer> OBSERVERS = new ArrayList<>();
void attach(Observer observer);
void detach(Observer observer);
void notifyInvestor();
}
目标类:股票
public class Stock implements Stocks{
private String stockName;
private int price;
public Stock(String stockName, int price) {
this.stockName = stockName;
this.price = price;
}
public Stock() {
}
public String getStockName() {
return stockName;
}
public void setStockName(String stockName) {
this.stockName = stockName;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public void attach(Observer observer) {
OBSERVERS.add(observer);
}
@Override
public void detach(Observer observer) {
OBSERVERS.remove(observer);
}
@Override
public void notifyInvestor() {
if(price >= 25*1.05 || price <= 25*0.95){
System.out.println("通知:股票价格变动幅度超过5%!");
for (Observer observer: OBSERVERS) {
observer.upDate();
}
} else {
System.out.println("股票价格变化幅度没有超过5%!!");
}
}
}
抽象观察者类
public interface Observer {
void upDate();
}
具体观察者类A
public class ConcreteObserverA implements Observer {
private String name;
private Stock stock;
public ConcreteObserverA(String name, Stock stock) {
this.name = name;
this.stock = stock;
}
public ConcreteObserverA(String name) {
this.name = name;
}
@Override
public void upDate() {
System.out.println("通知"+name+":"+stock.getStockName()+"的股票价格变化幅度超过5%,股票价格为:"+stock.getPrice());
}
}
具体观察者类B
public class ConcreteObserverB implements Observer {
private String name;
public ConcreteObserverB(String name, Stock stock) {
this.name = name;
this.stock = stock;
}
public ConcreteObserverB(String name) {
this.name = name;
}
private Stock stock;
@Override
public void upDate() {
System.out.println("通知"+name+":"+stock.getStockName()+"的股票价格变化幅度超过5%,股票价格为:"+stock.getPrice());
}
}
具体观察者类C
public class ConcreteObserverC implements Observer {
private String name;
private Stock stock;
public ConcreteObserverC(String name, Stock stock) {
this.name = name;
this.stock = stock;
}
public ConcreteObserverC(String name) {
this.name = name;
}
@Override
public void upDate() {
System.out.println("通知"+name+":"+stock.getStockName()+"的股票价格变化幅度超过5%,股票价格为:"+stock.getPrice());
}
}
测试类
public class Test {
public static void main(String[] args) {
System.out.println("设计模式,2020006924,于鑫");
Stock stock1 = new Stock("股票1",25);
System.out.println(stock1.getStockName()+"的股价为:"+stock1.getPrice());
Observer obs1,obs2,obs3;
obs1 = new ConcreteObserverA("smith",stock1);
obs2 = new ConcreteObserverB("tom",stock1);
obs3 = new ConcreteObserverC("李白",stock1);
stock1.attach(obs1);
stock1.attach(obs2);
stock1.attach(obs3);
stock1.setPrice(22);
stock1.notifyInvestor();
}
}
本文来自博客园,作者:街酒,转载请注明原文链接:http://www.cnblogs.com/sorrymine/p/17421523.html
API纯代码开发:PhalApi开源接口框架(派框架),接口,从简单开始!PhalApi是一个PHP轻量级开源接口框架,致力于快速开发接口服务。支持HTTP/SOAP/RPC等协议,可用于搭建接口/微服务/RESTful接口/WebServices。承诺永久免费,可用于商业用途。支持自动生成接口文档、自动进行参数校验、自动生成单元测试代码、自动拥有CURD数据接口、自动安装程序,让接口开发更简单、更高效、更专业。PhalApi2.x是全新版本系列,将持续更新,给你全新的开发体验。移植自PhalApi1.x,主要采用composer,遵循PSR-4,并支持命名空间。PhalApi2.x支持PHP5.3及以上版本,并支持PHP7。PhalApi2.x一键安装1、composer安装PhalApi2.x $composercreate-projectphalapi/phalapi 2、使用HTTP访问接口 http://localhost/phalapi/public/ 3、查看在线接口文档 http://localhost/phalapi/public/docs.php复制API接口的
我们已经成功的搞定了全局域名的增删改查功能。接下来就嵌入到接口库调试层中吧。关于这里的设计呢?我们就不能按照之前全局请求头的设计了,因为全局请求头是可以多选的,但是全局域名只能单选。打开P_apis.html,找到调试层的html代码。我们来进行思考,这个选择全局域名的功能,我个人觉得放在那个自动弹出的下拉列表最好。因为它和其他全局域名还有其他普通域名都是互斥的关系,也就是混在一起,任选其一。所以代码中我们找到那个控制下拉列表的datalist,给它填上公共域名:注意图中的这个option,也就是实际显示的内容,我们这里需要好好思考一下:我们这里host存放的应该会是一个全局变量-域名。不能存全局域名的host值,这样的话,那就起不到域名一变,接口域名跟着变的目的了。所以存放的肯定和全局请求头一样,是这个全局域名的id,而name则用来展示和描述,诱导用户选择,但是实际保存的也就是在输入框内的应该是id,所以上图写的看着没啥问题,但是我们看看效果:先看域名设置中的已有域名:再看看实际选择效果:选中后: 是不是很难看,根本看不明白。所以这里我们要麻烦一点,改成:再看看效果:这次是不是看的
游戏开发中的矩阵与变换介绍矩阵组件和恒等矩阵缩放转换矩阵旋转变换矩阵变换矩阵的基础翻译转换矩阵全部放在一起剪切变换矩阵(高级)转换的实际应用在转换之间转换位置相对于自身移动对象将变换应用于变换倒置转换矩阵这一切在3D中如何运作?表示3D旋转(高级)介绍阅读本教程之前,建议您通读并理解我之前发的向量数学教程,因为本教程需要向量知识。本教程介绍了转换以及如何使用矩阵在Godot中表示它们。它不是有关矩阵的完整深入指南。变换在大多数情况下都以平移,旋转和缩放的形式应用,因此我们将重点介绍如何用矩阵表示那些变换。本指南大部分内容都使用Transform2D和Vector2进行2D方面的研究,但是3D中的工作方式却非常相似。注意 正如前面提到的教程,一定要记住,在陀,Y轴点是很重要的倒在2D。这与大多数学校教线性代数的方法相反,Y轴指向上方。 注意 约定是X轴为红色,Y轴为绿色,Z轴为蓝色。本教程使用颜色编码以匹配这些约定,但我们还将用蓝色表示原始矢量。 矩阵组件和恒等矩阵单位矩阵表示没有平移,旋转和缩放的变换。让我们从身份矩阵及其组成与视觉外观的关系开始。矩阵具有行和列,并且转换矩阵具有关于每
关于SSH服务的暴力枚举,应用场景主要包括外围的边界突破以及内网的横向移动,所以可能需要在多种平台上使用这样的工具,本文主要介绍几款工具,包括python版、Go语言版、C/C++版、C#版等,根据自己的应用场景选择适合的版本即可。Python版SSH-Brute-Forcer(python2)项目地址:gitclonehttps://github.com/d3vilbug/Brutal_SSH使用之前需要安装一个库:pip2install-rrequirements.txt查看帮助信息:python2brutal_SSH.py指定用户名和密码,针对单个IP的暴力破解:python2brutal_SSH.py-i127.0.0.1-p22-U/root/usernames.txt-P/root/passwords.txt不支持批量目标检测,需要自己编写bash脚本来批量调用改项目。C#版C#主要适用于Windows平台,需要依赖系统上的.NetFramework框架。RedLoginhttps://github.com/ParsingTeam/RedLogin编译环境VS2015+.n
一、导入数据库1、建空数据库格式:mysql>createdatabase数据库名; 举例:mysql>createdatabasedatabase_name;2、导入数据库2.1方法一:终端命令行直接导入(常用):格式:mysql-u用户名-p数据库名<数据库名.sql举例:mysql-uuser_name-pdatabase_name<database_name.sql2.2方法二:进入SQL命令行导入选择数据库mysql>usedatabase_name;设置数据库编码mysql>setnamesutf8;导入数据(注意sql文件的路径)mysql>source/home/abc/abc.sql;二、导出数据库:1、导出数据和表结构:格式:mysqldump-u用户名-p密码数据库名>数据库名.sql 举例:mysqldump-uuser_name-pdatabase_name>database_name.sql2、只导出表结构格式:mysqldump-u用户名-p密码-d数据库名>数据库名.sql 举例:mysqldu
论文信息:NewcombeRA,IzadiS,HilligesO,etal.KinectFusion:Real-timedensesurfacemappingandtracking[C]//201110thIEEEInternationalSymposiumonMixedandAugmentedReality.IEEE,2011:127-136.由于这篇论文首次提出TSDF这种三维模型表示形式,其中难免有许多公式化的表达,作为一个初学者,我首先只能通读大概了解方法的思路,然后结合网上一些优质的解读文章才大致理解其公式化的表达。本篇文章就先作为一个“文字纯享版”,做一个论文内容的梳理,也供希望了解KinectFusion以及TSDF大致思想的人进行参考。至于详细的理论部分,我会再开一篇“公式推导版”进行重点解释(又挖一个坑)。摘要本文提出的实时建图系统,使用移动的深度相机和GPU,可以在可变照明条件下准确绘制室内任意场景的地图,重建结果是稠密表面,便于展示以及AR应用。当前的相机位姿也在同步更新,位姿估计考虑了已采集的所有深度信息,而不仅仅是上一帧。主要亮点有:·提出TSDF这种模型表示
现在大部分的App都上传图片的功能,比如设置用户头像、聊天发送图片、发表动态、论坛帖子等。上传图片需要先从选择手机中选择要上传的图片,所以图片选择器在App中是很常见的组件,一般的手机都会自带一个图片选择器。不过很多App并不喜欢用手机自带的选择器,而是自己实现一个图片选择器。比如微信的图片选择器就做的很好。所以我也仿照微信的样式和交互效果,自己做了一个图片选择器:ImageSelector。ImageSelector支持图片的单选、限数量的多选和不限数量的多选。支持图片预览和图片文件夹的切换。项目已经上传到了我的GitHub,欢迎大家下载和使用。本篇文章我将为大家介绍ImageSelector是如何现实的。由于ImageSelector的项目代码比较多,所以这篇文章只讲解ImageSelector的实现思路和分析主要的项目代码。想要看完整代码的同学请到GitHub下载项目。至于ImageSelector的使用,在我的另一篇文章中有详细的介绍:《Android仿微信的图片选择器ImageSelector的使用》。先上效果图:要实现一个图片选择器,需要做的主要就是以下几个事情:1、从手机
HTTP是应用层的协议,同时也是无状态的协议,所以也就有了COOKIE技术的发展,关于COOKIE和SESSION以及TOKEN这些我就不详细的解释了,在我的书籍《Python自动化测试实战》里面有很详细的解释。本节继续沿着Python测试实战(十)的主题来看Pytest测试框架对token的处理和API的案例应用实战。在案例里面,应用了Flask-JWT,关于JWT部分改天我在博客里面详细的写下。对之前的源码增加token的验证,最新的案例代码为: #!/usr/bin/python3 #coding:utf-8 fromflaskimportFlask,make_response,jsonify,abort,request fromflask_restfulimportApi,Resource fromflask_httpauthimportHTTPBasicAuth fromflaskimportFlask fromflask_jwtimportJWT,jwt_required,current_identity fromwerkzeug.securityimportsafe_s
文章目录1.scrapy初试1.1.创建项目1.2.其中将会创建以下的文件:1.3.编写第一个爬虫1.3.1.spider代码中内容解析1.3.2.以下是spider目录下的demo.py的代码1.4.spider的爬取1.5.spider中的数据存取scrapy初试创建项目 打开cmd,在终端输入scrapystartprojecttutorial,这里将在指定的文件夹下创建一个scrapy工程 其中将会创建以下的文件: scrapy.cfg:项目的配置文件tutorial/:该项目的python模块。之后您将在此加入代码。tutorial/items.py:项目中的item文件.tutorial/pipelines.py:项目中的pipelines文件.tutorial/settings.py:项目的设置文件.tutorial/spiders/:放置spider代码的目录.importscrapy classDmozItem(scrapy.Item): title=scrapy.Field() link=scrapy.Field() desc=scrapy.Field()复制 定
外卖产品下单到收货参与到的角色有用户、商家、骑手、以及平台系统;这四个角色和角色各个对应的场景活动构成了外卖产品的业务流程。 用户从下单到收货的整个业务场景的流转需要多个角色的支持配合。 下单到收货参与到的角色有用户、商家、骑手、以及平台系统,想清楚各个场景对应的关系。下单到收餐的流转主要依靠这些角色的完美供应。 我们来具体分析这几种角色: 第一:对应的C端用户的角色,用户的相关权限为下单、支付、催单、退单、评价。 第二:商家、出餐者,店铺的相关权限为通知骑手来取餐、出餐。 第三:骑手,骑手的权限为送餐。 第四:平台系统,平台系统的功能为短信服务、奖惩机制、运力分配等相关功能。 前端订单展示 前端订单系统主要包括2大块的展示:订单信息和订单状态,其实用户更多的是关心订单状态。 1.订单信息: 配送信息: 配送服务、配送骑手、骑手距离、预计到达时间、期望时间、配送地址;是必须展示的要素,来提升用户体验,便于用户查看,实时准确得知食物信息。配送地址、联系方式是骑手送达的根据。 订单信息: 订单号码、下单时间、支付方式;是必须展示的要素,便于用户核对订单。
小诀窍:不妨尝试从交付质量上打败对手关于作者:小姬,某知名互联网公司产品专家,对数据采集、生产、加工有所了解,期望多和大家交流数据知识,以数据作为提出好问题的基础,发觉商业价值。0x00前言我将整理文章分享数据工作中的经验,因为业务内容上的差异,可能导致大家的理解不一致,无法体会到场景中的诸多特殊性,不过相信不断的沟通和交流,可以解决很多问题。今天我们首先分析一下职场基本功,为什么要重视需求质量,常见的数据需求文档改怎么写。以下,Enjoy:0x01为什么要重视需求质量如果想快速的提高自己,但是不知道从哪里开始,不妨尝试从工作中将最为常见的需求文档质量提高,相信我,一份有优秀的需求文档,就可以让你打败了大多数的数据同行。为什么要重视需求质量PRD是产品经理最直接,最重要的交付物;PRD的功底最容易体现专业能力,依靠逻辑和描述能力,直观反映产品思路;PRD曝光次数较高,是最佳的印象产品,产品的开发依赖技术人员,PRD的设计才是产品人员的核心;最佳赢得口碑,给人以靠谱的感觉的交付物;锻炼编导能力,梳理思维逻辑,提高业务水平的最好方式。我的数据需求产品文档主要有:项目背景、项目范围、目标收益
这篇文章是关于pandasql,Yhat写的一个模拟R包sqldf的Python库。这是一个小而强大的库,只有358行代码。pandasql的想法是让Python运行SQL。对于那些来自SQL背景或仍然「使用SQL思考」的人来说,pandasql是一种利用两种语言优势的好方式。在本介绍中,将在为数据探索和分析构建的集成开发环境(IDE)Rodeo中用pandasql开始运行。Rodeo是一个开源、完全免费的工具。如果你是R使用者,那么它与RStudio具有类似感觉的工具。到目前为止,Rodeo只能运行Python代码,但上周我们添加一些其他语言的语法高亮到编辑器(markdown,JSON,julia,SQL,markdown)。你可能已经阅读或猜到了,我们对Rodeo有很大的计划,包括添加SQL支持,以便你可以在Rodeo内运行SQL查询,即使没有我们的方便pandasql。01.下载Rodeo首先从Yhat网站上的Rodeo页面下载RodeoforMac,Windows或Linux。如果你好奇,一点背景在背后,pandasql使用该pandas.io.sql模块在DataFrame
编程语言有上千种,但是流行的不过10来种,那些我们经常使用的编程语言都是谁在什么时候创造出来的呢?CasperBeyer为我们进行了整理。(本文节选)1957年约翰·巴克斯(JohnBackus)创建全世界第一套高阶语言FORTRAN,这是程序员真正意义上使用的第一种语言。1959年葛丽丝·穆雷·霍普(GraceHopper)发明了第一个面向企业的面向业务的编程语言,为“面向商业的通用语言”简称COBOL。1964年JohnKemeny和ThomasKurtz认为编程太困难了,他们需要回到基础上来,于是,他们称自己发明的编程语言为BASIC。1970年NiklausWirth很喜欢开发语言,于是开发了多种语言,最终,他发明的Pascal成为当时世界上最受欢迎的语言之一。他还提出了一句计算机领域人尽皆知的法则:算法+数据结构=程序,这个公式对计算机科学的影响程度不亚于戈登·摩尔的摩尔定律。1972年丹尼斯·里奇(DennisRitchie)在贝尔实验室上班上到无聊的时候,他决定发明带有花括号的语言,于是C语言诞生了,最终还取得了巨大的成功。之后,他又添加了分段错误等友好的功能来提高工作效
问题说明今天在使用pocketsphinx_continuous识别中文wav文件是,报如下错误:>pocketsphinx_continuous-hmmzh_broadcastnews_ptm256_8000-lmzh_broadcastnews_64000_utf8.DMP-dictzh_broadcastnews_utf8.dic-infilemyfile.wav ERROR:"continuous.c",line136:Inputaudiofilehassamplerate[44100],butdecoderexpects[16000]复制问题原因这个myfile.wav是我从一个mp3文件转换过来的,其中是采样率是44100HZ,而pocketsphinx_continuous需要使用16000HZ的音频文件。具体文件是什么采样率,在linux上可以使用soxi命令查看,比如:$soximyfile.wav InputFile:'myfile.wav' Channels:1 SampleRate:44100 Precision:1
原型图图片.png重要的实现代码vargetMemo=function(pageNo,name){ $('#dataDiv').html(""); $.ajax({ url:basePath+"/signIn/set/getSignSetListPage", datatype:'json', type:"POST", data:{"pageNo":pageNo,"name":name}, dataType:"json", success:function(data){ if(data!=null) { tPages=data.totalPages; curPage=data.currentPage; pgSize=data.sizeOfPage; vartableShow=""; $.each(data.signSetList,function(i,item){ tableShow+="<d
数据动态早报,让您了解数据新变化,新创造和新价值。一、通信行业数据动态1诺基亚软件组合助力运营商网络在智能化及自动化实现大幅提升。【慧聪通信网】2广东移动总经理简勤:运用信息化、大数据手段助力精准扶贫。广东移动总经理简勤建议运用信息化和大数据手段,精准地甄别扶贫对象,建立精准扶贫大数据管理平台,加快推动精准扶贫工作实施。【中国通信网】二、电子商务数据动态1电商之后是“数商”双创问题要用大数据解决。浪潮集团董事长孙丕恕建议,针对双创领域,中国需要加快大数据资源的流通和交易,建立大数据交易联盟;对于中国政府,建议加快购买云服务,把各地政府业务系统部署到统一云平台。【新浪网】2政府报告提出要“促进电商、快递进社区进农村”。农村市场成为电商战略发展的新重地。电商下乡关键在于激活农村市场消费潜力。应抓住“互联网+”的政策机遇,通过线上线下的融合,将电商自身的品牌优势和本地经销商的渠道优势结合起来。【中国信息产业网】三、互金行业数据动态1“3·8”女性大数据调查显示,七成女性投资过互联网金融产品。【网易网】2朗迪峰会:需利用大数据提高金融科技效率。中国互联网金融的发展中,群体诈骗和个人信用不良都会
String 概述 java.lang.String类代表字符串,java程序中的所有字符串文字都是此类的对象。 注: 字符串的内容是不会发生改变的,它的对象在创建后不能被更改。 String是java定义好的类,定义在java.lang包下故使用时不需要导入包 //拼接字符串是产生了一个新的字符串! Stringname="wdadwa"; Stringname2="aaa"; System.out.println(name+name2); //这个是创建了一个新的字符串bbb再把bbb赋值给了a Stringa="aaaaa"; a="bbbbb"; 复制 创建String对象的俩种方式 直接赋值 Stringname="wdadwa"; 复制 new方法 Strings1=newString();//空参构造 Strings2=newString("字符串");//传递一个字符串,根据传递的内容再创建一个新的字符串对象 //根据字符数组创建字符串 char[]chs={'a','b','c'}; Strings3=newString(chs);//一旦new后就无法更
为什么要加锁 如果多个线程同时访问共享资源时,我们通常需要锁的机制,保证在某个时刻,只有一个线程可以对这个资源进行操作,其他线程需要等待这个锁的释放才能继续处理。主要保证数据一致性 synchronized锁行不行? 在单机应用,可以使用, 但是在分布式系统中,因为是多个机器,不能使用线程级别的jvm锁,只能借助其他中间件来实现分布式锁, 分布式锁的三个属性: 互斥性(MutualExclusion):同一时刻只有一个客户端持有锁 避免死锁(Deadlockfree):设置锁的存活时间(TimeofLive)ttl 容错(Faulttolerance):避免单机故障,锁服务要有一定的容错性 一、SETNX RedisSetnx(SETIFNOTEXISTS) 命令如下 >SETNXKEY_NAMEVALUE 返回结果 如果设置成功(不存在这个key),返回1,如果设置失败(已经存在这个key),返回0 二、SET >SETKEYVALUE 返回结果 设置成功返回OK 在实现方式上可以使用RedisTemplate的setIfAbsent, 如果不存在(设置成功)返
多态在C++中是一个重要的概念,通过虚函数机制实现了在程序运行时根据调用对象来判断具体调用哪一个函数。 具体来说就是:父类类别的指针(或者引用)指向其子类的实例,然后通过父类的指针(或者引用)调用实际子类的成员函数。在每个包含有虚函数的类的对象的最前面(是指这个对象对象内存布局的最前面)都有一个称之为虚函数指针(vptr)的东西指向虚函数表(vtbl),这个虚函数表(这里仅讨论最简单的单一继承的情况,若果是多重继承,可能存在多个虚函数表)里面存放了这个类里面所有虚函数的指针,当我们要调用里面的函数时通过查找这个虚函数表来找到对应的虚函数,这就是虚函数的实现原理。注意一点,如果基类已经插入了vptr,则派生类将继承和重用该vptr。vptr(一般在对象内存模型的顶部)必须随着对象类型的变化而不断地改变它的指向,以保证其值和当前对象的实际类型是一致的。 以上这些概念都是C++程序员很熟悉的,下面通过一些具体的例子来强化一下对这些概念的理解。 1. #include<iostream> usingnamespacestd;
StringBuffer类的练习——对称字符串 判断一个键盘录入的字符串是否是对称字符串例如"abc"不是对称字符串,"aba"、"abba"、"aaa"、"mnanm"是对称字符串 分析:1、第1个字符与最后一个字符进行比较2、第2个字符与倒数第2个字符进行比较3、... 比较的次数:字符串的长度(length())/2 importjava.util.Scanner; publicclassStringBufferDemo10{ publicstaticvoidmain(String[]args){ //创建键盘录入对象 Scannersc=newScanner(System.in); System.out.println("请输入您想要判断的字符串:"); StringstringLine=sc.next(); &