引言
在学习Java基础的一些知识的时候,会逐渐接触、感受到开发方面的问题:
诸如内存空间的控制,时间效率的把控,安全性,方便性等等
设计模式的概念:
设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。
(一) 单例模式
我们不妨想象一个问题:
假设有这样一个类,我们在全局会频繁的调用它,那么我们便会在使用的时候去创建一个新的对象使用,之后再自动销毁。。。
那么这就会导致空间和时间两方面的低效。
单例模式解决的便是一个全局使用的类频繁地创建与销毁
代码实现:
public class Tool {
private static Tool tool = new Tool();
private Tool(){}
public static Tool getInstance() {
return tool;
}
}
- 定义一个静态属性,类加载时便初始化
- 将构造方法定义为私有,这样无法创建新对象
- 定义一个获取实例的公有方法,每次调用都获取的是同一个实例
大大节省了时间和空间
此设计模式有几种实现方式,解决的是在多线程工作下不能保持高性能的问题
(二) 工厂模式
很多时候,书写代码会创建一个有一个的类。当全局的其它地方需要调用此类的时候,便要书写创建对象的语句。
但仔细想想,正因为是我们自己书写的代码,所以我们才清楚此句的用途。若是去使用别人的代码,这么做是不是有点“私闯民宅”的意思了呢。
其实也就是为了表达这样一种思想:
就好比我们去提一辆车,我们只会关心提出来的车,而不会关心它是如何从工厂中加工出来的。
工厂模式便是若想创建一个对象,只要知道其名称就可以了
汽车工厂示例:
public interface Car {
void get() ;
}
public class Lexus implements Car{
@Override
public void get() {
System.out.println("你获得了一辆雷克萨斯");
}
}
public class Benz implements Car{
@Override
public void get() {
System.out.println("你获得了一辆奔驰");
}
}
定义一个工厂类,我们之后的需求向工厂索要
public class Factory {
public Car getCar(String car) {
if (car == null)
return null;
if ("Lexus".equals(car))
return new Lexus();
else if ("Benz".equals(car))
return new Benz();
return null;
}
}
这时有一个顾客:
public class Costumer {
public static void main(String[] args) {
Factory factory = new Factory();
Car car = factory.getCar("Lexus");
car.get();
car = factory.getCar("Benz");
car.get();
}
}
只需要向工厂说明自己的需求即可。
工厂模式提供了一种创建对象的最佳方式
不过其缺点也是很明显的:
每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖
(三) 包装模式
这一点在Connection对象连接池技术时深有体会,当我们使用完连接对象之后,想要将其通过 close 方法将其放回池中而不是销毁。
即在不更改源码的基础上实现新的功能。
包装模式便是加强原类的一种设计模式
以明星出道为例:
public interface Person {
void eat();
void sing(int money);
void dance(int money);
}
public class Actor implements Person{
private String name;
public Actor(String name) {
this.name = name;
}
public void eat() {
System.out.println(name + "开始吃饭");
}
public void sing(int money) {
System.out.println(name + "收到" + money + ", 开始唱歌");
}
public void dance(int money) {
System.out.println(name + "收到" + money + ", 开始跳舞");
}
}
此时刚刚出道,演出频繁
public class Action {
public static void main(String[] args) {
Person person = new Actor("刘德华");
person.eat();
person.sing(100);
person.dance(200);
}
}
现在红便天下,合作的事情便交给经纪人处理:
public class Proxy {
private Person person;
public Proxy(Person person) {
this.person = person;
}
public void eat() {
person.eat();
}
public void sing(int money) {
if (money <= 10000) {
System.out.println("事务繁忙,抽不开身");
return;
}
person.sing(money / 2);
}
public void dance(int money) {
if (money <= 20000) {
System.out.println("事务繁忙,抽不开身");
return;
}
person.dance(money / 2);
}
}
public class Action {
public static void main(String[] args) {
Person person = new Actor("刘德华");
Proxy proxy = new Proxy(person);
proxy.eat();
proxy.sing(20000);
proxy.dance(20000);
}
}
这便达成了 既不修改源码,又加强了其功能 的目的
与其相似的一种代理模式是 静态代理,其书写模式大同小异,省去了规范行为的接口