您的位置:首页 > 编程语言 > Java开发

Java设计模式一

2016-12-27 22:07 246 查看
本文内容来自慕课网系列课程,记录下学习的内容。

Java设计模式一

单例模式

有些对象我们只需要一个,比如:配置文件、工具类、线程池、缓存、日志对象等。如果创造出多个实例,就会导致许多问题,比如占用过多资源,不一致的结果等。

饿汉模式

饿汉模式:类加载的时候就会创建唯一的一个类实例

public class Singleton {

//1.将构造方法私有化,不允许外部直接创建对象
private Singleton() {
}

//2.创建类的唯一实例
private static Singleton instance = new Singleton();

//3.提供一个用于获取实例的方法
public static Singleton getInstance() {
return instance;
}

}


懒汉模式

懒汉模式:类加载的时候并没有去创建类的实例

public class Singleton2 {
//1.将构造方法私有化,不允许外边直接创建对象
private Singleton2() {
}

//2.声明类的唯一实例,使用private static修饰
private static Singleton2 instance;

//3.提供一个用户获取实例的方法
public static Singleton2 getInstance() {
if (instance == null) {
instance = new Singleton2();
}
return instance;
}
}


区别:

饿汉模式加载类时比较慢,但在运行时获取对象的速度比较快,线程安全

懒汉模式加载类时比较快,但在运行时获取对象的速度比较慢,线程不安全

参考Thread-Safe and a Fast Singleton Implementation – Singleton Design Pattern in java,线程安全的单例模式,可以这样写:

package com.crunchify.tutorials;

public class CrunchifySingleton {

private static CrunchifySingleton instance = null;

protected CrunchifySingleton() {
}

// Lazy Initialization (If required then only)
public static CrunchifySingleton getInstance() {
if (instance == null) {
// Thread Safe. Might be costly operation in some case
synchronized (CrunchifySingleton.class) {
if (instance == null) {
instance = new CrunchifySingleton();
}
}
}
return instance;
}
}


模板方法模式

抽象基类定义框架,为所有子类提供一个算法框架

基本方法

抽象方法

可选的钩子

Template方法(final)

具体子类

实现基类中的抽象方法

覆盖钩子方法

准备一个抽象类,将部分逻辑以具体方法的形式实现,然后声明一些抽象方法交由子类实现剩余逻辑,用钩子方法给予子类更大的灵活性,最后将方法汇总构成一个不可改变的模板方法。

使用场景:

1.算法或操作遵循相似的逻辑

2.重构时(把相同的代码提取到父类中)

3.重要、复杂的算法,核心算法设计为模板方法

优点:封装性好、复用性好、屏蔽细节、便于维护

这里使用的是一个炮制饮料的例子,分为炮制咖啡和茶,总共4步,其中有两步不同。

其抽象基类为
RefreshBeverage
,其中的
addCondiments
brew
方法要留给子类去实现:

/**
* 抽象基类,为所有子类提供一个算法框架
*
* 提神饮料
*/
public abstract class RefreshBeverage {

public final void prepareBeverageTemplate() {
//步骤1 将水煮沸
boilWater();
//步骤2 炮制饮料
brew();
//步骤3 将饮料倒入杯中
pourInCup();
//步骤4 加入调味料
addCondiments();
}

//抽象的基本方法
protected abstract void addCondiments();

private void pourInCup() {
System.out.println("将饮料倒入杯中...");
}

//抽象的基本方法
protected abstract void brew();

private void boilWater() {
System.out.println("将水煮沸...");
}

}


创建
Coffee
子类,实现抽象类的方法:

/*
* 具体子类,提供了coffee的制备方法
*/
public class Coffee extends RefreshBeverage {

@Override
protected void addCondiments() {
System.out.println("加入糖和牛奶...");
}

@Override
protected void brew() {
System.out.println("用沸水冲泡咖啡...");
}

}


钩子使子类更灵活

现在假设另一中情况,假设有些顾客并不想添加配料,即不想执行
addCondiments()
方法,怎样做会更灵活?

Hook,钩子函数,提供一个默认或空的实现。具体的子类可以自行决定是否挂钩以及如何挂钩。

修改
prepareBeverageTemplate()
方法如下:

public final void prepareBeverageTemplate() {
//步骤1 将水煮沸
boilWater();
//步骤2 炮制饮料
brew();
//步骤3 将饮料倒入杯中
pourInCup();
if(isCustomerWantsCondiments()){
//步骤4 加入调味料
addCondiments();
}
}

/*
* Hook,钩子函数,提供一个默认或空的实现
* 询问用户是否加入调料
*/
protected boolean isCustomerWantsCondiments() {
return true;
}


在子类中就可以覆写
isCustomerWantsCondiments()
方法

适配器模式

所谓适配器,就是连接“源”和“目标”的纽带

适配器模式将一个类的接口,转换成客户期望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。

这个例子是插座适配器,一个笔记本只能使用三相插座,但是现在只有一个二相插座



使用组合的方式实现称为对象适配器

特点:把”被适配者”作为一个对象组合到适配器类中,以修改目标接口包装被适配者

三相插座接口
ThreePlugInterface


/*
* 目标方法接口
*
* 三相插座接口
*/
public interface ThreePlugInterface {

//使用三相电流供电
public void powerWithThree();

}


二相插座类
GBTwoPlug


public class GBTwoPlug {

//使用二相电流供电
public void powerWithTwo() {
System.out.println("使用二相电流供电");
}

}


TwoPlugAdapter
适配器类实现
ThreePlugInterface
接口,持有一个
GBTwoPlug


/**
* 二相转三相的插座适配器
* @author Miller
*
*/
public class TwoPlugAdapter implements ThreePlugInterface {

private GBTwoPlug plug;

public TwoPlugAdapter(GBTwoPlug plug) {
this.plug = plug;
}

@Override
public void powerWithThree() {
plug.powerWithTwo();
}

}


笔记本类
NoteBook


public class NoteBook {

private ThreePlugInterface plug;

public NoteBook(ThreePlugInterface plug) {
this.plug = plug;
}

//使用插座充电
public void charge() {
plug.powerWithThree();
}

public static void main(String[] args) {
GBTwoPlug twoPlug = new GBTwoPlug();
ThreePlugInterface threePlug = new TwoPlugAdapter(twoPlug);
NoteBook noteBook = new NoteBook(threePlug);
noteBook.charge();
}

}


使用继承方式称为类适配器

特点:通过多重继承不兼容接口,实现对目标接口的匹配,单一的为某个类而实现适配

TwoPlugAdapterExtends
类继承自
GBTwoPlug
类,实现了
ThreePlugInterface
接口

public class TwoPlugAdapterExtends extends GBTwoPlug implements ThreePlugInterface {

@Override
public void powerWithThree() {
this.powerWithTwo();
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java java设计模式