https://blog.csdn.net/jack__chiang/article/details/70208886
1.设计模式的分类
创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
1.工厂模式(Factory Method):
- 普通工厂模式
- 多个工厂方法模式
- 静态工厂方法模式
1.1 普通工厂模式:
如果存在多个类实现了同一个接口,则这些类的实例化统一在一个”工厂类“中进行:
// 1. 发送短信和邮件的接口
public interface Sender {
public void Send();
}
//2.1 . 发送邮件的实现类
public class MailSender implements Sender {
public void Send() {
System.out.println("发送邮件!");
}
}
//2.2 . 发送短信的实现类
public class SmsSender implements Sender {
public void Send() {
System.out.println("发送短信!");
}
}
// 3 创建工厂类
public class SendFactory {
//工厂方法
public Sender produce(String type) {
if ("mail".equals(type)) {
return new MailSender();
} else if ("sms".equals(type)) {
return new SmsSender();
} else {
System.out.println("请输入正确的类型!");
return null;
}
}
}
//测试类
public class FactoryTest {
public static void main(String[] args) {
SendFactory factory = new SendFactory();
Sender sender = factory.produce("sms");
sender.Send();
}
}
1.2 多个工厂模式
在普通方法模式基础上,直接在工厂类中提供创建类实例的方法,而不需要先筛选下发字符:
//将上面的代码做下修改,改动下SendFactory类就行
//这个就不用根据用户传的字符串类创建对象了
public class SendFactory {
public Sender produceMail(){
return new MailSender();
}
public Sender produceSms(){
return new SmsSender();
}
}
//测试类
public class FactoryTest {
public static void main(String[] args) {
SendFactory factory = new SendFactory();
Sender sender = factory.produceMail();
sender.Send();
}
}
1.3 静态工厂方法模式
将上面多个工厂方法模式的方法设置为静态,不需要创建实例,直接调用:
public class SendFactory {
public static Sender produceMail(){
return new MailSender();
}
public static Sender produceSms(){
return new SmsSender();
}
}
//测试类
public class FactoryTest {
public static void main(String[] args) {
Sender sender = SendFactory.produceMail();
sender.Send();
}
}
总结:涉及到实现了一个接口的多个类的实例化时,创建一个“工厂类”,统一管理这些类的实例化过程;
2.抽象工厂模式:
把“工厂类”抽象化:
例子:
//发送短信和邮件的接口
public interface Sender {
public void Send();
}
//发送邮件的实现类
public class MailSender implements Sender {
public void Send() {
System.out.println("发送邮件!");
}
}
//发送短信的实现类
public class SmsSender implements Sender {
public void Send() {
System.out.println("发送短信!");
}
}
//给工厂类一个接口
public interface Provider {
public Sender produce();
}
//两个工厂的实现类
public class SendMailFactory implements Provider {
public Sender produce(){
return new MailSender();
}
}
public class SendSmsFactory implements Provider{
public Sender produce() {
return new SmsSender();
}
}
//测试类
public class Test {
public static void main(String[] args) {
//实例化一个工厂类
Provider provider = new SendMailFactory();
// 通过工厂类实例化需要创建的类
Sender sender = provider.produce();
sender.Send();
}
}
总结:之前是一个工厂类可以实例化多个最终类,现在是多个工厂类,每个工厂类仅仅就实例化一个最终类,把最终类的多样性转移到工厂类的多样性上;
简单点说,类似于利用多态性,如果B extends A ,B 中重写的A 中的方法,在创建A 时调用 A a = new B(); 则后续对a 的方法的调用实际上调用B 中的;
Provider provider = new SendMailFactory(); Provider 是一个抽象类,provider 是一个抽象类的实例化对象,如果向修改provider 以后的操作,可以就修改 new 后面的方法,增加拓展性!!!!
其实还可以写一个类,继承SendMailFactory?
3.单例模式(Singleton)
在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在。这样的模式有几个好处:
1.减少反复创建同一个类的系统压力;
2.省去new ,减轻GC;
//TODO
4.建造者模式(Builder)
google 源码中很常见的模式, 类在创建一个再一步步“填写”它的成员变量,方法;
class A {
int a;
long b;
string c;
void set_a(int new_a){ ... }
void set_b(long new_b){ ... }
...
...
int get_a();
long get_b();
...
}
5.原型模式(Prototype)
将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象。在Java中,复制对象是通过clone()实现的:
public class Prototype implements Cloneable {
public Object clone() throws CloneNotSupportedException {
Prototype proto = (Prototype) super.clone();
return proto;
}
}
一个原型类,只需要实现Cloneable接口,覆写clone方法,此处clone方法可以改成任意的名称,因为Cloneable接口是个空接口,你可以任意定义实现类的方法名,如cloneA或者cloneB,因为此处的重点是super.clone()这句话,super.clone()调用的是Object的clone()方法,而在Object类中,clone()是native的,说明这个方法实现并不是使用java语言
//TODO FURTHER DISCUSSING
结构型模式
6.适配器模式(Adapter)
类似于
A extends B implement C
这样A 的实例对象中,既可以调用B中实现的方法,也可以调用C 的方法。如果B 和C 需要进行通信,就可以直接在A中进行参数处理;
6.1 对象适配器模式
类似于
class A implement C {
public A( B b){
this.b = b;
}
}
B 是A的构造参数,在A 的实例对象里可以直接调用B的信息,同时A 是C的实现类,A 中也可以调用C 的参数,最终B/C 通信;
6.2 接口适配器模式
A 为接口类, B 为抽象类且同时实现了A ,C extends B,重写方法
public interface A {
public void method_A();
}
public abstract B implement A {
public void method_A(){
....
};
}
class C extends B {
// 重写
public void method_A(){
....
};
public void method_C(){
... ...
}
}