Public and Private Interfaces in ruby
Your latest client is a bank, and they’ve tasked you with requiring customers to enter their password in order to make withdrawals.
Currently, this is what they’ve got:
class Customer
attr_reader :funds def initialize(funds, password)
@funds = funds
@password = password
end def remove_funds(amount)
@funds -= amount
end
end
Let’s break that apart. You can paste that whole class into irb to follow along.
When a customer is initialized, it receives a specified amount of funds and a password is set.
diego = Customer.new(500, "udacious")
# => #<Customer:0x007fcdb48ca5a8 @funds=500 @password="udacious">
Thanks to the attr_reader, you can see the value of his current funds.
diego.funds
# => 500
And the remove_funds method allows funds to be removed from the customer’s account.
Checking on the funds again confirms this.
diego.remove_funds(50)
# => 450
diego.funds
# => 450
These methods, funds and remove_funds, are part of the Customer class’ API, or application programming interface.
An API is, according to Wikipedia, “a set of routines, protocols, and tools for building software applications”.
Well, that’s vague.
“API” is a popular term in recent years, but many people use it without quite understanding what it means. Think of methods like remove_funds as your way of interfacing with the Customer class. These methods are the keys to accessing information about a particular customer.
There isn’t currently a way to access the @password instance variable.
It could be said that the customer’s password can’t be accessed by the customer’s public API.
In this situation, that’s a good thing! You don’t want information like a password to be publicly available to other objects.
Let’s implement a method called withdraw_securely, which takes two arguments, amount andpassword.
If the password entered matches the customer’s password, go ahead and remove the funds. Otherwise, nothing happens.
class Customer
attr_reader :funds def initialize(funds, password)
@password = password
@funds = funds
end def remove_funds(amount)
@funds -= amount
end def withdraw_securely(amount, password)
if password == @password
remove_funds(amount)
end
end
end
Play around with this in irb to see it in action.
diego.withdraw_securely(50, "udacious")
# => 400
diego.withdraw_securely(100, "wrong password")
# => nil
diego.funds
# => 400
✨Hooray. Calling withdraw_securely using the correct password decreases the total funds by calling remove_funds,
while using the incorrect password does nothing.
There’s one issue here, can you spot it?
diego.remove_funds(75)
# => 325
diego.funds
# => 325
Malicious users can still withdraw funds directly using the remove_funds method!
Public and Private Interfaces in ruby的更多相关文章
- Ruby中访问控制符public,private,protected区别总结
重点关注private与protected public 默认即为public,全局都可以访问,这个不解释 private C++, “private” 意为 “private to this cla ...
- swift 中关于open ,public ,fileprivate,private ,internal,修饰的说明
关于 swift 中的open ,public ,fileprivate,private, internal的区别 以下按照修饰关键字的访问约束范围 从约束的限定范围大到小的排序进行说明 open,p ...
- public protect private. 草稿。
public protect private. 草稿. #include <iostream> #include <thread> #include <memory> ...
- Java修饰符public,private,protected及默认的区别
Java中访问修饰符public.private.protecte.default的意义讲解:public(接口访问权限): Java语言中访问限制最宽的修饰符,一般称之为“公共的”.被其修饰的类.属 ...
- C++中public,protected,private派生类继承问题和访问权限问题
C++中public,protected,private派生类继承问题和访问权限问题 当一个子类从父类继承时,父类的所有成员成为子类的成员,此时对父类成员的访问状态由继承时使用的继承限定符决定. 1. ...
- 【转载】C++中public,protected,private访问
第一:private, public, protected 访问标号的访问范围. 假如我们约定: 类内部-----指的是当前类类型的定义中,以及其成员函数的声明和定义中: 类外部-----指的是不在当 ...
- JAVA修饰符类型(public,protected,private,friendly)
转自:http://www.cnblogs.com/webapplee/p/3771708.html JAVA修饰符类型(public,protected,private,friendly) publ ...
- php public protected private属性实例详解
php 类中函数和类变量都有三个属性:public protected private,具体什么时候使用什么属性好纠结,特意找了个实例,这样看起来更清晰. public 表示全局,类内部外部子类都可以 ...
- C# 访问控制:public、private、protected和internal
平日工作时最常用的访问控制符是public和private,当看到prism里面大量使用protected的时候,觉得还是不太理解为啥. 所以就静下心来查找并理解了一下,这里记录下,以便回顾和交流. ...
随机推荐
- RockWare RockWorks的Ollydbg调试过程及注册机(破解)思路
最近拿到了RockWorks15的安装包,可惜没有破解,试用也只能用14天.用PEiD工具察看了一下,Delphi编写的程序,竟然没加壳.本想用OllyDBG调试进去爆破一下,不意发现注册码很简单,如 ...
- Sql Server 附加没有日志文件的数据库(.mdf)文件方法
附加数据库,附加的时候会提醒找不到log文件 针对以上现象有两个写法的语句能解决: 写法一: USE MASTER; EXEC sp_detach_db @dbname = 'TestDB'; EXE ...
- [POJ2155]Matrix(二维树状数组)
题目:http://poj.org/problem?id=2155 中文题意: 给你一个初始全部为0的n*n矩阵,有如下操作 1.C x1 y1 x2 y2 把矩形(x1,y1,x2,y2)上的数全部 ...
- 标准I/O
在程序运行时,会默认为我们打开三个流:标准输入流.标准输出流.标准出错流. 标准输入流一般对应我们的键盘 标准输出流一般对应显示器 标准出错流一般也对应显示器 1.标准输入流 在标准I/O中,java ...
- WCF入门 (14)
前言 上周去面试,跪了,这一年没什么长进,还是挺惭愧的. 得到的评语是:想的太多,做的太少. 做了一份面试题,最后一题是数据库的,写个查询.要查出Score有两次及两次以上超过79的Name和他的最高 ...
- easyui中tree控件添加自定义图标icon
来源于:http://blog.163.com/lintianhuanhai@126/blog/static/165587366201421704420256/ <!DOCTYPE html&g ...
- [Windows 64] (搬运)价值¥ 6,499的软件Navicat Premium11.2.11 最新版及其注册机
Navicat Premium可以连接6种数据库并开发> 转载于:http://www.52pojie.cn/thread-529020-1-1.html
- Address already in use: JVM_Bind<null>:80
Address already in use: JVM_Bind<null>:80 咱还是闲话少说,直接切入正题. 起因: 一直用Tomcat,但是前几天突然报错: java.net.Bi ...
- python 2.7的安装
最近准备入手学习python 这里我是按照:http://blog.csdn.net/jcjc918/article/details/11022345 来的 我在安装python 3 的时候发现上下左 ...
- list 和 str
list 和 str 两种类型数据,有不少相似的地方,也有很大的区别.本讲对她们做个简要比较,同时也是对前面有关两者的知识复习一下,所谓“温故而知新”. 相同点 都属于序列类型的数据 所谓序列类型的数 ...