1、装饰模式
**************************************************************************************************************************
不改变原内容的情况下,通过创建一个包装对象即装饰来包裹真实对象,实现保持对象原有功能并动态扩展。
**************************************************************************************************************************
设计原则:多用组合,少用继承
利用继承设计子类的行为,不仅编译时静态决定,而且所有子类都会继承到相同行为。利用组合扩展对象,可以 在运行时动态扩展。
**************************************************************************************************************************
装饰模式的特点:
a、装饰对象和真实对象有相同接口,这样客户端对象就能以和真实对象相同的方式和装饰对象交互。
b、装饰对象包含一个真实对象的引用(reference)
c、装饰对象接收所有来自客户端的请求,并转发给真实对象
d、装饰对象可以在转发请求之前或之后增加一些附属功能
**************************************************************************************************************************
实用性:(java的io也使用了装饰者模式)
a、给类增加一个附属值
b、动态增加功能并能动态撤销功能
c、小功能的组合排列实现大功能
d、类定义被隐藏或不能被使用时,或拓展功能需要产生大量子类时可用装饰模式
*************************************************************************************************************************
//定义装饰者的父类
public abstract class Decorator implements Drink{
public Drink drink; //要装饰的对象
public Derector(Drink drink){
this.drink = drink;
}
@Override
public String name() {
return drink.name();
}
@Override
public float price() {
return drink.price();
}
}
//定义装饰者类,椰果类
public class Cocount extends Decorator {
public Cocount(Drink drink) {
super(drink);
}
@Override
public String name () {
return "椰果" + super.name();
}
@Override
pulic float price () {
return super.price() + 0.8f; //椰果0.8元
}
}
//测试装饰类
public class TestDecorator {
pubic static void main () {
Drink drink = new MakeTea();
Cocount cocount = new Cocount(drink); //奶茶里添加椰果
System.out.println("第一杯奶茶为:" + cocount.name() + "价格为:" + cocount.price());
}
}
2、单例模式
懒汉式单例、饿汉式单例、登记式单例
单例模式特点:
a、只能有一个实例
b、必须创建自己唯一实例
c、必须给其他所有对象提供这一实例
在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序常被设计成单例。单例模式就是 为了避免不一致状态。
*******************************************************************************************************************************
a、懒汉式单例:
第一次调用时,实例化
public class Singleton {
private Singleton() {}
private static Singleton single = null;
public static SIngleton getInstance() { //静态工厂方法
if(single == null) {
single = new Singleton();
}
return single;
}
} //java反射机制可以实例private的构造方法,这里不做讨论。懒汉式单例模式是线程不安全的。
/est/测试类
public class Tmain {
public static void mian(String[] args) {
TestStream ts1 = TestSingleton.getInstance();
ts1.setName("jason")
TestStream ts2 = TestSingleton.getInstance();
ts2.setName("0593");
ts1.printInfo();
ts2.printInfo();
if(ts1 == ts2) {
System.out.println("创建的是同一个实例");
}else{
System.out.println("创建的不是同一个实例");
}
}
}
//结果-创建的是同一个实例,说明单例模式只会创建一个所有线程公用的实例
b、饿汉式单例模式
private class Singleton {
private Singleton () {}
private static final Singleton single = new Singleton();
public static Singleton getInstance() {
return single;
}
}
c、登记式单例(类似Spring里面的方法,将类名注册,下次从里面直接获取)
public class Singleton {
private static Map<String,Singleton> map = new HashMap<String,Singleton>();
static{
Singleton single = new Singleton();
map.put(single.getClass().getName(),single);
}
protected Singleton(){}
public static Singleton getInstance(String name){
if(name == null) {
name = Singeton.class.getName();
System.out,println("name == null" + "--->name=" + name );
}
if(map.get(name) == null) {
try{
map.put(name,(Singleton) Class.forName(name).newInstance());
}catch(InstancetiationException e) {
e.printStackTrace();
}catch(IllegalAccessException e) {
e.printStackTrace();
}catch(ClassNotFoundException e) {
e.printStackTrace();
}
}
return map.get(name);
}
//登记式单例实际上维护了一组单例类的实例,将这些实例存放在一个Map(登记簿)中。已登记过的实例,从Map 直接返回;没有登记过的,登记后返回。
3、适配器模式(包装模式)
ocp原则(开闭原则):一个软件实体应通过扩展增加功能,而不应该通过修改原码实现变化。
对象适配器模式和类适配器模式(一般多重继承)
*******************************************************************************************************************************
将一个接口适配成用户所期待的。适配器允许因为接口不兼容而不能一起工作的类工作在一起,具体将自己的接 口包裹在一个已存在的类中。
*******************************************************************************************************************************
要求接口中规定了所有要实现的方法,但使用时只实现其中的几个方法。
*******************************************************************************************************************************
//标准接口
interface Target {
public void request();
}
//Adaptor父类,具有所有功能
class Adaptee {
public void specificRequest() {
System.out.println("配给适配器的特殊功能");
}
}
//适配器类
class Adapter extends Adaptee implements Target {
public void request () {
super.specificRequest();
}
}
//测试类
public class Client {
public static void main(String[] args) {
Target concreteTarget = new Target();
concreteTarget.request(); //普通功能
Target adapter = new Adapeter();
adapter.request(); //适配器特殊功能
}
} //java不支持多线程,只能采用包装类实现。其实适配器什么都没有做,只是将Adaptee和Target黏合在一起,使这 两者可以通信