(一、间接调用)
假设现在有Friend、Someone、Stranger三个类,现在想要利用Someone来调用Stranger当中的方法,但是呢,又不能直接调用,这个时候呢就需要借助Friend这个类来进行间接的调用。
首先是建立这样一个Someone的类
public class Someone {
public void call(Friend friend){
friend.forward();
}
}
然后是建立这样的一个Friend类,这个类就是包含了Stranger类当中的方法,并且就是将该方法通过构造出能够调用Stranger中方法的方法
public class Friend {
private Stranger stranger=new Stranger();
public void forward() {
stranger.StrangerMethod();
}
//其他方法
public void friendMethod(){
System.out.println("这是朋友的方法");
}
}
下面是Stranger类的方法
public class Stranger {
public void StrangerMethod(){
System.out.println("这是陌生的方法");
}
}
接下来是main方法
public class Main {
public static void main(String[] args) {
Someone someone = new Someone();
someone.call(new Friend());
}
}
(二)
1、饿汉式单列类的源代码如下所示
public class Sing {
private static Sing sing=new Sing();//这个就是私有化这个实例
private Sing(){
}
public static Sing getInstance(){
return sing;//通过该方法获得实列
}
}
这个就是通过这个getInstance方法来获得该类的实例,并且这个类当中的构造方法是私有的,所以这个类是不能被继承的,于是该类就不会被其他类无限地进行调用。
2、懒汉式单例模式
懒汉式单列模式与饿汉式单列模式有相同的地方,也有不同的地方,相同的就是他们的构造方法都是私有的,并且只创造一个实例化,话不多说,直接奉上代码
public class Sing {
private static Sing sing=new Sing();//这个就是私有化这个实例
private Sing(){
}
synchronized public static Sing getInstance() {
if (sing == null) {
sing = new Sing();
}
return sing;
}
}
这个懒汉式单列模式之所以要加入synchronized,其目的就是想要同步这个方法,使之不会因为多线程的同时调用而创建多个实例,这样就违背了单列模式的原则,相反,如果设置了这个锁的话,就会有先来后到的感觉。从资源利用率上来说,饿汉式单列模式要稍微差一点,但是从速度和反应时间上来讲的话,饿汉式单列模式则比懒汉式单列模式要好一点。并且,根据相关资料的查询,饿汉式单列模式更符合java语言本身的特点。
单例模式的实例
对于单列模式,我们需要了解的东西还有很多,现在我来对它做一个介绍
首先创建一个单列模式类GlobalNum,其代码如下所示
public class GlobalNum {
private static GlobalNum globalNum = new GlobalNum();
private int num = 0;
private GlobalNum() {
}
public static GlobalNum getInstance() {
return globalNum;
}
public synchronized int getNum() {
return ++num;
}
}
上述方法用于创建这个单列之后,接下来就是编写一个测试方法,用于访问这个单列
public class SingleDemo {
//测试单列模式
public static void main(String[] args) {
NumThread threadA = new NumThread("线程A");
NumThread threadB=new NumThread("线程B");
threadA.start();;
threadB.start();//这个就是启动线程
}
}
class NumThread extends Thread {
private String threadName;
public NumThread(String name) {
threadName = name;//这个就是规定对应的名字是和这个相等的
}
//重写线程的run方法
public void run(){
GlobalNum gn=GlobalNum.getInstance();//这个就是对这个线程进行访问
for(int i=0;i<5;i++)
{
System.out.println(threadName+"第"+gn.getNum()+"次访问!");
try{
sleep(1000);
}catch(Exception e)
{
e.printStackTrace();
}
}
}
}
(三)
单列模式:
一个类只有一个实例,而且自行实例化并向整个系统提供这个实例;单例模式减少内存开支,避免对资源的多重占用,优化和共享源访问;但单列模式扩展难,不易测试。
工厂方法模式:
定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。
抽象工厂模式:
是工厂方法的升级,为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
建造者模式:
也叫生成器模式,将一个复杂对象的构建与其表示分类,使得同样的构建过程可以创建不同的表示。
原型模式:
用原型实例指定创建对象的种类,并通过复制这些原型创建新的对象。
(四)
public class Proxy implements Subject{
private Subject subject;
public Proxy(Subject subject){
this.subject=subject;
}
@Override
//实现请求方法
public void request() {
subject.request();
this.afterRequest();
this.beforeRequest();
}
//请求前的操作
public void beforeRequest(){
//预处理
}
//请求后的操作
public void afterRequest(){
//善后处理
}
}
还有以下代码
public class RealSuject implements Subject{
//业务逻辑处理
@Override
public void request() {
}
}
public interface Subject {
//定义请求一个方法
public void request();
}
上面附上的的代码是关于代理模式的代码,其目的就是想为对象提供一种代理以控制对这个对象的访问
代理模式提供以下三个角色
抽象主题(Subject)角色:该角色是真实主题和代理主题的共同接口
代理主题(Proxy)角色:也叫做委托类、代理类,该角色负责控制对真实主题的引用,负责在需要的时候创建或删除真实主题对象,并且在真实主题角色处理完毕前后做预处理和善后处理工作
真实主题(RealSuject)角色:该角色也叫做委托角色,是业务逻辑的具体执行者。
//这个是抽象主题
public interface IGamePlayer {
//定义请求一个方法
public void killBoss();
public void upGrade();
}
//这个是真实主题
public class GamePlayer implements IGamePlayer {
private String name="";
public GamePlayer(String name){
this.name=name;
}
public void killBoss(){
System.out.println(this.name+"在打怪");
}
public void upGrade(){
System.out.println(this.name+"成功升了一级");
}
}
//这个是代理主题,其中既有真实主题当中对应的方法,也有自己对应的方法,负责对真实主题的引用
import java.util.Date;
public class GamePlayerProxy implements IGamePlayer {
private IGamePlayer player=null;
public GamePlayerProxy(IGamePlayer player){
this.player=player;
}
//记录打怪时间
private void log(){
System.out.println("打怪时间"+new Date().toString());
}
public void killBoss(){
this.log();
player.killBoss();
}
public void upGrade(){
player.upGrade();
this.count();
}
private void count(){
System.out.println("升一级耗费50小时");
}
}
(五)
中介者模式
也称调停者模式,用一个中介对象封装一系列对象的交互,中介者使各对象不需要显式地相互作用,从而使其耦合松散,而且可以独立地改变他们之间的交互
观察者模式
定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新
备忘录模式
又称为快照模式,在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。
访问者模式
封装一些作用于某种数据结构中的各个元素的新的操作,它可以在不改变数据结构的前提下定义于作用这些元素的新的操作
状态模式
又称为状态对象模式,当一个对象内在状态改变时允许改变行为,这个对象看起来像改变了其类型
解释器模式
给定一门语言,定义他的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。
(六)
下面来介绍书中包含的所有的模式及其描述和类图
如果又不懂类图的说明的,我还附上了对应的类图详细说明,下图就是:
好了,小伙伴们,本期的设计模式就彻底结束了,我是明怀,一个在互联网摸爬滚打的程序猿,我们下期见!