Don't wanna be here? Send us removal request.
Text
服务提供者框架
参考:http://liwenshui322.iteye.com/blog/1267202
由于静态工厂方法返回的对象所属的类,在编写包含该静态工厂方法的类时可以不必存在。这种灵活的静态工厂方法构成了服务提供者框架的基础,如:JDBC 服务提供者框架是指这样一个系统:多个服务提供者实现一个服务,系统为服务提供者的客户端提供多个实现,并把他们从多个实现中解耦出来。
服务提供者框架各组件关系如下:
1.服务具体实现类和服务提供者实现类是服务提供者自己去实现。以JDBC为例,这2个模块由具体的数据库提供商来实现。
2.其他三个模块是java对数据库提供商怎么实现上面2个模块的一个约束。比如:提供服务者实现类必须实现服务提供者接口。才能成功注册到服务提供者注册类。以JDBC为例,所有的数据库提供商只需要按照接口里面定义的规则来操作,都能成功地使java连上他们的数据库。
以JDBC为例:
在Java中连接Mysql的源码如下:
Class.forName("com.jdbc.mysql.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","123");
从这个地方可以看出:只需要更换数据库的驱动名称与建立连接的URL,用户名等信息,就可以完全切换到另外一个数据库。数据库底部怎么操作的我们不清楚,也没必要清楚。我们获取的连接对象是Connection,查看java.sql.Connection这个类,会发现它只是一个接口。我们得到的只是一个接口,怎么可能能够操作数据库呢?其实这里得到的不是Connection接口,而是它的一个实现类,只是对于客户端不可见而已。这可能就是所谓的面向接口编程,客户端只需要知道它该知道的信息,服务端告诉客户端,你可以调用哪些方法。至于具体方法怎么实现是服务端的事情,客户端就不需要管,也不需要知道了。
自己写一个服务提供者框架,以广州地铁进出控制为例: 现有两种模式: 1.使用羊城通,进出刷卡。 2.使用单程票,进入刷单程票,出站回收单程票。
现在把两种模式分别分给 A公司做羊城通的部分 、B公司做单程票的部分,系统提供 服务定义接口、服务提供者接口、服务提供者注册类, 地铁闸机实现客户端调用功能。
服务定义接口:
/**
* 地铁服务接口
* 服务定义接口
*/
public interface SubwayInterface {
boolean in();
boolean out();
}
服务提供者接口:
/**
* 地铁服务提供者接口
* 服务提供者接口
*/
public interface SubwayProviderInterface {
SubwayInterface getInstance();
}
服务提供者注册类:
/**
* 地铁服务注册类
* 服务提供者注册类
*/
public class ServiceManager {
private static final Map<String,SubwayProviderInterface> providers = new ConcurrentHashMap<>();
private ServiceManager(){
}
public static void registerProvider(String name, SubwayProviderInterface provider){
providers.put(name,provider);
}
public static SubwayInterface getService(String name){
SubwayProviderInterface provider = providers.get(name);
if(provider == null){
throw new IllegalArgumentException("null");
}
return provider.getInstance();
}
}
A公司提供的服务
提供者实现类:
/**
* 服务提供者实现类 1
*/
public class SubwayProviderCardImpl implements SubwayProviderInterface {
static {
ServiceManager.registerProvider("羊城通", new SubwayProviderCardImpl());
}
@Override
public SubwayInterface getInstance() {
return new SubwayCardImpl();
}
}
A公司提供的服务具体实现类:
/**
* 通过羊城通使用地铁服务
* 服务具体实现类 1
*/
public class SubwayCardImpl implements SubwayInterface {
@Override
public boolean in() {
System.out.println("通过羊城通进入地铁");
/*
具体实现逻辑
*/
return false;
}
@Override
public boolean out() {
System.out.println("通过羊城通出站");
/*
具体逻辑
*/
return false;
}
}
B公司提供的服务提供者实现类:
/**
* 服务提供者实现类 2
*/
public class SubwayProviderTicketImpl implements SubwayProviderInterface {
static {
ServiceManager.registerProvider("单程票", new SubwayProviderTicketImpl());
}
@Override
public SubwayInterface getInstance() {
return new SubwayTicketImpl();
}
}
B公司提供的具体服务实现类:
/**
* 通过单程票使用广州地铁服务
* 服务具体实现类 2
*/
public class SubwayTicketImpl implements SubwayInterface {
@Override
public boolean in() {
System.out.println("通过单程票进入地铁");
return false;
}
@Override
public boolean out() {
System.out.println("通过单程票出站,回收单程票");
return false;
}
}
闸机客户端测试类:
/**
* 客户端测试类
*/
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
//使用 单程票公司提供的服务
Class.forName("com.zoujiejun.serviceproviderframework.ticket.SubwayProviderTicketImpl");
SubwayInterface subway = ServiceManager.getService("单程票");
subway.in();
subway.out();
//使用 羊城通公司提供的服务
Class.forName("com.zoujiejun.serviceproviderframework.card.SubwayProviderCardImpl");
SubwayInterface subway2 = ServiceManager.getService("羊城通");
subway2.in();
subway2.out();
}
}
服务提供者中的三个重要组件:服务接口(Service Interface)、提供者注册API(Provider Registration API)、服务访问API(Service Access API),第四个可选组件服务提供者接口(Service Provider Interface)。
0 notes
Text
创建和销毁对象(一):考虑使用静态工厂方法代替构造器
类可以提供一个静态方法,返回类的一个静态实例,如Boolean包装类的一个获取实例的静态方法
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
优势: 1、有名称。当一个类需要多个带有相同签名的构造器时,就用静态工厂方法代替构造器,并慎重选择名称以突出它们之间的区别。 如:BigInteger.probablePrime(int bitLength, Random rnd) 返回一个随机的素数。 2、不必在每次调用它们的时候都创建一个新对象。 3、可以返回其子类,在选择返回对象的类时有了更大的灵活性。 4、简化代码。
缺点: 1、整个类如果没有public 或 protected类型的构造器,则它将不能被继承,即不能作为超类,相当于final。 2、与其他静态方法在api文档中没有区别,不像构造器在api中可以标识出来
静态工厂方法惯用名称:
valueOf —— 返回的实例与其参数具有相同的值,实际上是一种类型转换方法
of —— valueOf简洁的替代,EnumSet中有使用
getInstance
newInstance ——同getInstance,保证每个返回的实例都与其他实例不同
getType —— Type表示工厂方法所返回的对象类型
newType
0 notes
Text
策略模式
策略模式定义:定义算法族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。
针对接口编程而非针对实现编程,可把需要实现的算法类型定义为一个接口,如现有接口
interface Sort(){
void sort();
}
然后编写它的实现类,如Class QuickSort()、Class ShellSort()等实现类通过不同的方式实现了接口方法。在需要调用该算法的地方把其声明为一个接口,然后用不同的实现类来实例化,如:
Sort sort = new QuickSort();
sort.sort();
从而充分运用多态,加强程序可拓展性;
如某类需要排序算法:
class data{
private Sort sort;
data(Sort sort){
this.sort = sort;
}
public void sort(){
sort.sort();
}
public static void main(Strings[] args){ Data data = new Data(new QuickSort()); data.sort(); } }
运用策略模式可以动态改变行为,如在main中把QuickSort换成ShellSort,可以使Data类运用不同的方法进行排序,但却不用对Data类做出任何的改动。
0 notes
Text
C++程序的组成部分
#include <iostream> //1
int main() //2
{
std::cout<<"hello, world";
return 0;//3
}
C++组成部分
1、预处理器编译指令#include
<标准头文件>
"非标准头文件"
iostream标准头文件包含对std::cout的定义。
2、程序的主体 main() C++程序开始的地方 可使用main()方法的变种, 如 int main(int argc, char* argv[]) ,用于允许用户提供命令行参数
3、返回值 一般运行成功返回0, 运行失败或异常返回负数 父程序可通过子程序的返回值判断子程序的运行状态
命名空间
类似于Java中的包,用于区分不同位置的同名函数。
两种使用方法:
using name space std; //类似于import java.util.*
using std::count; //类似于import java.util.Map
输入与输出
std::cout<<"hello"; std::cin>>Veriable;
0 notes
Text
Java 8 中常用的函数式接口
函数式接口 函数描述符
Predicate<T> T->boolean
Consumer<T> T->void
Function<T, R> T->R
Supplier<T> ()->T
UnaryOperator<T> T->T
BinaryOperator<T> (T, T)->T
BiPredicate<L, R> (L, R)->boolean
BiConsumer<T, U> (T, U)->void
BiFunction<T, U, R> (T, U)->R
//Java8 in action
0 notes