Java design patterns

Java有不少种模式,如下的是一些总结的模式。java

(1) 单例模式 (实现方式 私有构造器 + 私有静态自己的实例 + 共有实例方法返回自己的实例), 须要判断是否已经生成过实例)一个类只容许其有一个实例化对象 在并发程序中用的可能比较多, 涉及线程安全, 我本身知道的是Spring 依赖注入, 在容器中的Bean通常都是单例的..
public class Singelton { // 最平凡的实现方式
private volatile static Singelton singelton;
public static Singelton getInstance(){
if(singelton == null) {
synchronized {
if(singelton == null) {
singelton = new Singelton();
return singelton;
}
}
}
}
}
单例模式的三种实现方式:
饿汉方式: 
对象类型声明成static final 类型, 而且直接实例化 而后用getInstance()方法来获取变量引用 这样能够保证对象惟一
懒汉方式:
对象类型声明成 volatile static 类型
经过getInstance 的判断 来实现对象惟一, 可是这个要考虑到并发问题, 多线程状况下并不安全, 须要用双重检查机制, 而且把类型声明称volatile static
最好的方式(java语言 也就是由于jvm才特有的方法):
经过内部私有静态类来实现单例, 在这个类内部实例化一个static final的实例
而后用一个方法调用这个静态类的这个静态实例 他的优势就是结合了上头两种方式的全部优势, 便可以懒加载, 也能够保护线程安全,设计模式

(2)工厂模式(一个建立型设计模式) 有不少实现的例子 好比说不少带有*BeanFactrory的类 都是工厂模式的体现 他经过形参等 生成不一样的对象 LoggerFactory BeanFactory 等. 其实就是经过工厂的方式, 返回某个接口不一样的实例, 其实就是能够根据客户要求的返回她想要的产品..
工厂模式分为三种:
第一种: 简单工厂(静态工厂) 有一个工厂类拥有一个静态的方法, 用来产生产品实例, 经过传递参数的不一样来区分生成哪一个产品实例.
第二种: 工厂方法 : 这个是用来解决简单工厂存在的问题 好比: 增长一个产品简单工厂须要对工厂类代码进行修改, 增长一个判断条件, 这样就增长了代码的复杂程度, 工厂方法为了解决这个问题, 经过多态的方式来实现不一样的工厂类来生产不一样的产品. 即会有一个工厂接口, 经过实现工厂接口的方式实现新的工厂类, 来代替修改工厂类代码, 这样会使得代码耦合度下降. 
(更深一步, 工厂类甚至能够加入产品的业务方法, 直接调用自己建立的产品的方法).
第三种: 抽象工厂 为产品分类, 将纵向的产品实现类, 横向化, 就是组成更大的产品工厂 具体实现如图:(手画工厂图) 用来生产复杂的产品.
(3)观察者模式 用于一对多 或者是 一对一 关系中 在一中有什么改动 会致使和他有关系的多(也就是观察者们也发生变更) 
Redis 实现异步消息队列 有一种实现方式叫: 发布订阅者模式 相似可是 调度方式不同 观察者模式由发布者调度 而 另外一种模式不是 他有单独的调度中心
例子:
public interface Subject {
public void attach(Observer o);
public void detach(Observer o);
public void notice();
}
interface Observer{
public void update();
}
class Student implements Observer{
String teacherPhone = "";
Teacher teacher ;
public Student(String phone,Teacher t){
teacher = t;
teacherPhone = phone;
}
@Override
public void update() {
teacherPhone = teacher.getPhone();
}
public void show(){
System.out.println(teacherPhone);
}
}
class Teacher implements Subject{
private String phone;
private ArrayList<Observer> students;
public Teacher(){
phone = "";
students = new ArrayList<Observer>();
}
@Override
public void attach(Observer o) {
students.add(o);
}
@Override
public void detach(Observer o) {
students.remove(o);
}
@Override
public void notice() {
for(Observer o:students){
o.update();
}
}
public String getPhone(){
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
notice();
}
}
Test:
public static void main(String[] args) {
Teacher teacher = new Teacher();
Student s = new Student("",teacher);
Student s1 = new Student("",teacher);
teacher.attach(s);
teacher.attach(s1);
teacher.setPhone("13215646");//核心在这个set方法上 他的变更致使不少都发生了改变
s.show();
s1.show();
}安全

(4) 外观模式(门面模式) Facade Pattern
这个感受是最简单的 他经过一个门面类 将具体操做隐藏在方法中 客户只须要调用方法 不用知道具体的实现 这样就很好
(说的个更加科学一点就是, 这个模式的做用就是实现客户端和子系统的解耦, 用户在调用客户端接口的时候咱们能够将它具体调用的操做隐藏起来, 只须要给他提供一个门面接口, 这样就可使得调用更加简单)
public void Solution(){
Analyze a = new Analyze();//这三个类的具体实现不知道 不过用户只要对调用方法 自动都会产生结果
Think t = new Think();
Finally f = new Finally();
a.Analyze();
t.Think();
f.Finally();
}
public class Test {
public static void main(String[] args) {
Problem p = new Problem();
p.Solution();
}
}多线程

(5)组合模式 解释一下这个模式是什么, 首先他是用来解决树形对象模型的(这个说的有一点不是很确切, 我感受组合模式是用来解决相似有多种不一样的对象, 可是他们之间还有必定的类似性 相似于这种问题就能够用组合模式来解决, 组合模式能够将他们抽象到一个Component), 就是例如文件系统这种树形的结构. 他的方式是经过将叶子节点(文件), 非叶子结点(文件夹) , 抽象成一个component类或者是接口, 而后叶子节点和非叶子结点, 分别实现一下这个类, 而后经过重写方法的形式来实现树形遍历
还分为两种: 透明组合模式 安全组合模式并发

(6)命令模式
先上图:(传统的命令模式 可能都不是这么用)
这个模式能够类比于开关, 有不一样的功能选项, 当你按不一样的按钮的时候, 会有不一样的物品反应你的命令(暂时理解就是这个含义) 
对于上图来讲, 一个命令模式须要一个Invoker调用者, 也就是发出命令的人, 它关联了一个command对象(或者是一系列command对象), 而后咱们须要具体的command实现类, 用来调用Handler(某个功能具体的实现类), 这个图还少了个模块就是咱们应该将Handler抽象成接口, 这样的话, 若是添加删除具体的Handler也能够减小咱们修改以前的代码. 而后咱们的逻辑关系是, 咱们的实现类接口会关联一个Handler, 经过set方法set具体的Handler实现类以后, 调用具体的功能模块.................(这是传统的)异步

可是如今的命令名模式不少状况下都不是直接将Handler和Command 耦合起来, 由于咱们要知足设计的高内聚弱耦合的原则, 因此 -> 演变出了一个命令队列.jvm

 

(7)装饰模式 (分为透明装饰模式和半透明装饰模式) 
而后简单的说一下这个模式是什么, 这个模式是为了为被修饰的类添加一个方法, 其实就是装饰一下一个类, 使其具备其余功能, 具体的实现方式是: 首先咱们须要一个被装饰的抽象构建Component(其有一个须要被修饰的方法), 而后咱们须要一个抽象装饰器类Decorator, 实现咱们的须要被修饰的抽象构建, 而后与其关联一下. 最后咱们须要一个具体的装饰器类ConcreteDecorator, 它实现咱们的抽象装饰器类, 而后加入咱们要加入的 方法, 这样咱们就能够为咱们的具体实现类set一个ConcreteComponent, 以后就能够调用被修饰的方法.jsp

(8)代理模式 这个模式较难 单独创建了一个文档 详见 java学习/代理模式ide

(9)原型模式 这个模式就是获取原型的一个克隆对象, 克隆对象和原型不能是同一个对象的引用. 在java中能够调用基类Object 的clone() 方法, 可是要重写这个方法必须实现Cloneable
这个模式有两种级别: 
浅克隆 : 就是上头说到的那种状况, 实现一个Cloneable 接口 这个只能克隆基本类型, 可是对于引用类型 他只能克隆引用类型的地址 因此说引用类型的对象克隆以后两个实例指向的仍是一个对象
深克隆 : 这个是经过实现一个Serializable 接口来实现 , 把对象实例放到流里, 而后再取回来, 这样就能够得到一个新的克隆实例
(10)建造者模式
建造者模式相似于抽象工厂模式, 抽象工厂是将不一样的产品进行组合, 组合成新产品, 他是用来生产复杂产品(也就是类)的. 相似的, 建造者模式是用来产生复杂对象的, 在这里二者的核心区别就是, 建造者模式使用来生产复杂对象的, 他把一个对象的不一样属性的建造抽象化, 也就是说一个对象的属性的值是经过调用建造函数获取的, 相对的抽象工厂是用来说不一样种的产品(也就是类) 组合起来生成新的产品的过程, 他的组装对象是类. 而建造者模式组装的是属性函数

首先他分为, 要生产的对象 Actor , 建造者(AbstrackBuilder, *Builder) , 控制者
抽象建造者有一个Actor类型的属性, 而且有为这个Actor 的各个属性赋值的函数, 具体建造者继承抽象建造者, 而后实现具体的建造函数, 最后控制者须要一个具体建造者做为参数, 控制者分别调用具体建造者的建造函数, 而后获取这个建造出来的Actor 也就是说我能够选择不调用某个函数, 这样就很灵活

(11)适配器模式
这个模式的含义个人理解是, 咱们有一个(目标/目的)抽象类的两个方法, 可是在某个地方已经有实现了的现成的方法, 那么咱们想要不用本身再从新实现一遍这两个同样的方法有两种办法 1.把以前实现的代码copy过去, 2. 就是写一个目标抽象类的适配器, 
对于第二种方法也就是实现这个抽象类而后提供一下这两个方法的实现, 而后这两个方法的实现是经过关联已经实现过这两个方法的类而后调用他们的方法来实现, 这样就避免了copy代码从而增长代码长度, 并且冗余度高的问题.

而后适配器模式还分为对象适配器模式和类适配器模式, 对象适配器模式是经过关联的方式来调用适配者的方法, 可是类适配器模式是经过继承的方式, 因为java语言单继承的特性, 其实这个类适配器模式不多被使用, 
适配器模式有一种双向适配器模式, 这个其实就是能够双向适配. 适配者是双方的.还有一种叫缺省适配器, 缺省适配器的最大的特色就是适配器类是一个抽象的, 他不用实现目标接口的全部方法, 而是能够只实现几个.

(12)桥接模式
废话很少说先来上个图
来解释一下这个桥接模式, 首先他的做用是分离一个实体中两种或者多种维度的抽象, 把他们抽象成抽象类 -> 关联 -> 抽象接口的模式 这样就能够了 要增添新的类型, 只须要在他对应的维度下建立一个对应的具体实现类, 而后就能够实现复杂功能的解耦.

(13) 享元模式 (不是特别经常使用)
这个模式的做用就是, 实现一个享元工厂, 将一些具备相同功能的对象集中起来, 减小对象的数量, 下降系统由于对象冗余致使的内存消耗, 最典型的例子运用了享元模式的就是String这个对象. 每次建立新对象的时候他老是要先在常量池中查找是否是已经有了相同字符串的引用若是有了的话就不用在建立一个新的对象了, 只要把以前那个字符串的引用返回便可

(14)职责链模式
责任链模式是什么尼? 其实责任链模式就是对于一系列的处理, 请求须要在一个链上依次传递. (相似于jsp的过滤器和Spring的拦截器) 
责任链模式分为纯的责任链模式和不纯的责任链模式. 
纯的责任链就是责任链的每个handler只能选择两种处理1: 处理请求 2: 传给下一个
不纯的责任链其实就是handler在处理完以后能够再传给下一家。

固然,还有其余的模式,就不一一阐述了。仅供参考。

相关文章
相关标签/搜索