Java设计模式

一、什么是设计模式

设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。
使用设计模式是为了可重用代码、避免程序大量修改,同时使代码更容易被他人理解、并且保证代码可靠性。

模式:在某些场景下,针对某类问题的某种通用的解决方案。

场景:项目所在的环境

问题:约束条件,项目目标等

解决方案:通用、可复用的设计,解决约束达到目标。

1、设计模式的三个分类

创建型模式:对象实例化的模式,创建型模式用于解耦对象的实例化过程。
结构型模式:把类或对象结合在一起形成一个更大的结构。
行为型模式:类和对象如何交互,及划分责任和算法。

23种设计模式,其中,创建型有5种,结构型有7种,行为型有11种。

创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式

行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

在这里插入图片描述
在这里插入图片描述

二、各分类模式的关键点

1、创建型模式

创建型模式5种。

单例模式:某个类只能有一个实例,提供一个全局的访问点。

工厂方法:定义一个创建对象的接口,让子类决定实例化那个类。

抽象工厂:创建相关或依赖对象的家族,而无需明确指定具体类。

建造者模式:封装一个复杂对象的构建过程,并可以按步骤构造。

原型模式:通过复制现有的实例来创建新的实例。

2、结构型模式

结构型模式7种。

适配器模式:将一个类的方法接口转换成客户希望的另外一个接口。

桥接模式:将抽象部分和它的实现部分分离,使它们都可以独立的变化。

组合模式:将对象组合成树形结构以表示“”部分-整体“”的层次结构。

装饰模式:动态的给对象添加新的功能。

亨元(蝇量)模式:通过共享技术来有效的支持大量细粒度的对象。

外观模式:对外提供一个统一的方法,来访问子系统中的一群接口。

代理模式:为其他对象提供一个代理以便控制这个对象的访问。

3、行为型模式

行为型模式11种。

访问者模式:在不改变数据结构的前提下,增加作用于一组对象元素的新功能。

模板模式:定义一个算法结构,而将一些步骤延迟到子类实现。

策略模式:定义一系列算法,把他们封装起来,并且使它们可以相互替换。

状态模式:允许一个对象在其对象内部状态改变时改变它的行为。

观察者模式:对象间的一对多的依赖关系。

备忘录模式:在不破坏封装的前提下,保持对象的内部状态。

中介者模式:用一个中介对象来封装一系列的对象交互。

迭代器模式:一种遍历访问聚合对象中各个元素的方法,不暴露该对象的内部结构。

解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器。

命令模式:将命令请求封装为一个对象,使得可以用不同的请求来进行参数化。

责任链模式:将请求的发送者和接收者解耦,使的多个对象都有处理这个请求的机会。

三、概说23种设计模式

1、单例模式

创建型设计模式。

简单说来,单例模式(也叫单件模式)的作用就是保证在整个应用程序的生命周期中,任
何一个时刻,单例类的实例都只存在一个(当然也可以不存在)。

单例模式确保某一个类只有一个实例,而且自行实例化,并向整个系统提供这个实例单例模式。单例模式只应在有真正的“单一实例”需求时才可使用。

全局变量和单例模式的区别为:首先,全局变量是对一个对象的静态引用,全局变量确实可以提供单例模式实现的全局访问这个功能,但是它并不能保证应用程序中只有一个实例;其次,编码规范也明确指出应该要少用全局变量,因为过多使用全局变量,会造成代码难读;最后全局变量并不能实现继承(虽然单例模式在继承上也不能很好地处理,但是还是可以实现继承的)。而单例模式在类中保存了它的唯一实例——这个类,它可以保证只能创建一个实例,同时它还提供了一个访问该唯一实例的全局访问点。

使用单例模式,需要注意的是,单例模式用来保证系统中一个类只有一个实例。单例类的构造函数必须为私有,同时单例类必须提供一个全局访问点。

单例模式的主要优点就是节约系统资源、提高了系统效率,同时也能够严格控制客户对它的访问。也许就是因为系统中只有一个实例,这样就导致了单例类的职责过重,违背了“单一职责原则”,同时也没有抽象类,所以扩展起来有一定的困难。

(1)饿汉模式

/**
 * 
 * @author Vincent
 * 线程安全 但是容易产生垃圾对象,没有加锁执行效率会比较高 
 * 但不是懒加载 类一加载的时候就进行初始化 浪费内存
 *
 */
 
1. public class Singleton {
2. // 直接创建对象
3. public static Singleton instance = new Singleton();
4.
5. // 私有化构造函数
6. private Singleton() {
7. }
8.
9. // 返回对象实例
10. public static Singleton getInstance() {
11. 	return instance;
12. 	}
13. }

(2)懒汉式

1. public class Singleton {
2. // 声明变量
3. private static volatile Singleton singleton = null;
4.
5. // 私有构造函数
6. private Singleton() {
7. }
8.
9. // 提供对外方法
10. public static Singleton getInstance() {
11. 	if (singleton == null) {
12.			 synchronized (Singleton.class) {
13. 			if (singleton == null) {
14. 				singleton = new Singleton();
15. 			}
16. 		}
17. 	}
18. 	return singleton;
19.	 }
20. }

2、工厂设计模式

什么是工厂模式

一、
工厂 模式专门负责实例化有大量公共接口的类。工厂模式可以动态块决定将哪一个类实例化,而不必事先知道每次要实例化哪一个类。
客户类和工厂类是分开的。消费者无论什么时候需要某种产品,需要做的只是向工厂提出请求即可。消费者无须修改就可以接纳新产品。当然也存在缺点,就是当产品修改时,工厂”类也要做相应的修改。

二、
工厂模式分为工厂方法模式和抽象工厂模式。

工厂方法模式分为三种:
1)普通工厂模式,就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建。
2)多个工厂方法模式,是对普通工厂方法模式的改进,在普通工厂方法模式中,如果传递的字符串出错,则不能正确创建对象,而多个工厂方法模式是提供多个工厂方法,分别创建对象。
3)静态工厂方法模式,将上面的多个工厂方法模式里的方法置为静态的,不需要创建实例,直接调用即可。

三、
工厂方法模式的设计类图:
在这里插入图片描述
Product 为产品的接口或基类,所有产品都实现这个接口或抽象类( 例如ConcreteProduct),这样就可以在运行时根据需求创建对应的产品类。Creator实现了对产品的所有操作方法,而不实现产品对象的实例化。产品的实例化由Creator 的子类来完成。

(1)普通工厂模式

1. public interface Sender {
2. public void Send();
3. }
4. public class MailSender implements Sender {
5.
6. @Override
7. public void Send() {
8. 			System.out.println("this is mail sender!");
9. 		}
10.}
11. public class SmsSender implements Sender {
12.
13. @Override
14. 	public void Send() {
15. 		System.out.println("this is sms sender!");
16. 	}
17. }
18. public class SendFactory {
19. 	public Sender produce(String type) {
20. 		if ("mail".equals(type)) {
21. 			return new MailSender();
22. 		} else if ("sms".equals(type)) {
23. 				return new SmsSender();
24. 			} else {
25. 				System.out.println("请输入正确的类型!");
26. 				return null;
27. 				}
28. 		}
29. }

(2)多个工厂方法模式

该模式是对普通工厂方法模式的改进,在普通工厂方法模式中,如果传递的字符串出错,则不能正确创建对象,而多个工厂方法模式是提供多个工厂方法,分别创建对象。

1. public class SendFactory {
2. 		public Sender produceMail(){
3. 			return new MailSender();
4. 		}
5.
6. 		public Sender produceSms(){
7. 			return new SmsSender();
8. 		}
9. }
10.
11. public class FactoryTest {
12.	 public static void main(String[] args) {
13. 		SendFactory factory = new SendFactory();
14. 		Sender sender = factory.produceMail();
15. 		sender.send();
16. 	}
17. }

(3)静态工厂方法模式

将上面的多个工厂方法模式里的方法置为静态的,不需要创建实例,直接调用即可。

1. public class SendFactory {
2. 		public static Sender produceMail(){
3. 			return new MailSender();
4. }
5.
6. public static Sender produceSms(){
7. 		return new SmsSender();
8. 		}
9. }
10.
11.
12. public class FactoryTest {
13. 	public static void main(String[] args) {
14. 		Sender sender = SendFactory.produceMail();
15. 		sender.send();
16. 	}
17. }

(4)抽象工厂模式

一、
工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则。
所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。

二、
抽象工厂模式的设计类图:
在这里插入图片描述
AbstractProductA和AbstractProductB代表2个产品家族,实现这些接口的类代表具体的产品。AbstractFactory 为创建产品的接口,能够创建这个产品家族的中所有类型的产品,它的子类可以根据具体情况创建对应的产品。

1. public interface Provider {
2. 		public Sender produce();
3. }
4. -------------------------------------------------------------------------------------
5. public interface Sender {
6. 		public void send();
7. }
8. -------------------------------------------------------------------------------------
9. public class MailSender implements Sender {
10.
11. @Override
12. public void send() {
13. 		System.out.println("this is mail sender!");
14. 	}
15. }
16. -------------------------------------------------------------------------------------
17. public class SmsSender implements Sender {
18.
19. @Override
20. public void send() {
21. 		System.out.println("this is sms sender!");
22. 	}
23. }
24. -------------------------------------------------------------------------------------
25. public class SendSmsFactory implements Provider {
26.
27. @Override
28. public Sender produce() {
29. 		return new SmsSender();
30. 	}
31. }

1. public class SendMailFactory implements Provider {
2.
3. @Override
4. public Sender produce() {
5. 		return new MailSender();
6. 	}
7. }
8. -------------------------------------------------------------------------------------
9. public class Test {
10. public static void main(String[] args) {
11. 		Provider provider = new SendMailFactory();
12. 		Sender sender = provider.produce();
13. 		sender.send();
14. 	}
15. }

3、建造者模式(Builder)

工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象,所谓复合对象就是指某个类具有不同的属性,其实建造者模式就是前面抽象工厂模式和最后的 Test 结合起来得到的。

1. public class Builder {
2. 		private List<Sender> list = new ArrayList<Sender>();
3.
4. 		public void produceMailSender(int count) {
5. 			for (int i = 0; i < count; i++) {
6. 				list.add(new MailSender());
7. 			}
8. 		}
9.
10. public void produceSmsSender(int count) {
11. 		for (int i = 0; i < count; i++) {
12. 			list.add(new SmsSender());
13. 		}
14. 	}
15. }

1. public class Builder {
2. 		private List<Sender> list = new ArrayList<Sender>();
3.
4. 		public void produceMailSender(int count) {
5. 			for (int i = 0; i < count; i++) {
6. 				list.add(new MailSender());
7. 			}
8. 		}
9.
10. 	public void produceSmsSender(int count) {
11. 		for (int i = 0; i < count; i++) {
12. 			list.add(new SmsSender());
13. 		}
14. 	}
15. }
1. public class TestBuilder {
2. 		public static void main(String[] args) {
3. 			Builder builder = new Builder();
4. 			builder.produceMailSender(10);
5. 		}
6. }

4、适配器设计模式

什么是适配器模式

一、
适配器模式也称为变压器模式,它是把一个类的接口转换成客户端所期望的另一种接口,从而使原本因接口不匹配而无法-起工作的两个类能够-起工作。适配类可以根据所传递的参数返还一个合适的实例给客户端。

二、
在这里插入图片描述

三、
适配器模式将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配所造成的类的兼容性问题。
主要分为三类:类的适配器模式、对象的适配器模式、接口的适配器模式。

(1)类的适配器模式

1. public class Source {
2. 		public void method1() {
3. 			System.out.println("this is original method!");
4. 		}
5. }
6. -------------------------------------------------------------
7. public interface Targetable {
8. /* 与原类中的方法相同 */
9. public void method1();
10. /* 新类的方法 */
11. public void method2();
12. }
13. public class Adapter extends Source implements Targetable {
14. @Override
15. 	public void method2() {
16. 		System.out.println("this is the targetable method!");
17. 	}
18. }
19. 
20. public class AdapterTest {
21. 	public static void main(String[] args) {
22. 		Targetable target = new Adapter();
23. 		target.method1();
24. 		target.method2();
25. 	}
26. }

(2)对象的适配器模式

基本思路和类的适配器模式相同,只是将 Adapter 类作修改,这次不继承 Source 类,而是持有 Source 类的实例,以达到解决兼容性的问题。

1. public class Wrapper implements Targetable {
2. 		private Source source;
3.
4. 		public Wrapper(Source source) {
5. 			super();
6. 			this.source = source;
7. 		}
8.
9. 		@Override
10. 	public void method2() {
11. 		System.out.println("this is the targetable method!");
12. 	}
13.
14. 	@Override
15. 	public void method1() {
16. 		source.method1();
17. 	}
18. }
19. --------------------------------------------------------------
20. public class AdapterTest {
21.
22. public static void main(String[] args) {
23. 	Source source = new Source();
24. 	Targetable target = new Wrapper(source);
25. 	target.method1();
26. 	target.method2();
27. 	}
28. }

(3)接口的适配器模式

接口的适配器是这样的:有时我们写的一个接口中有多个抽象方法,当我们写该接口的实现类时,必须实现该接口的所有方法,这明显有时比较浪费,因为并不是所有的方法都是我们需要的,有时只需要某一些。
此处为了解决这个问题,我们引入了接口的适配器模式,借助于一个抽象类,该抽象类实现了该接口,实现了所有的方法,而我们不和原始的接口打交道,只和该抽象类取得联系,所以我们写一个类,继承该抽象类,重写我们需要的方法就行。

5、装饰模式(Decorator)

顾名思义,装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例。

1. public interface Sourceable {
2. 		public void method();
3. }
4. ----------------------------------------------------
5. public class Source implements Sourceable {
6. 	@Override
7. 		public void method() {
8. 			System.out.println("the original method!");
9. 		}
10. }
11. ----------------------------------------------------
12. public class Decorator implements Sourceable {
13. 	private Sourceable source;
14. 	public Decorator(Sourceable source) {
15. 		super();
16. 		this.source = source;
17. 	}
18.
19. 	@Override
20. 	public void method() {
21. 		System.out.println("before decorator!");
22. 		source.method();
23. 		System.out.println("after decorator!");
24. 	}
25. }
26. ----------------------------------------------------
27. public class DecoratorTest {
28. 	public static void main(String[] args) {
29. 		Sourceable source = new Source();
30. 		Sourceable obj = new Decorator(source);
31. 		obj.method();
32. 	}
33. }

6、策略模式(strategy)

策略模式定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响到使用算法的客户。

需要设计一个接口,为一系列实现类提供统一的方法,多个实现类实现该接口,设计一个抽象类(可有可无,属于辅助类),提供辅助函数。

策略模式的决定权在用户,系统本身提供不同算法的实现,新增或者删除算法,对各种算法做封装。
因此,策略模式多用在算法决策系统中,外部用户只需要决定用哪个算法即可。

1. public interface ICalculator {
2. 		public int calculate(String exp);
3. }
4. ---------------------------------------------------------
5. public class Minus extends AbstractCalculator implements ICalculator {
6.
7. 	@Override
8. 	public int calculate(String exp) {
9. 		int arrayInt[] = split(exp, "-");
10. 	return arrayInt[0] - arrayInt[1];
11. 	}
12. }
13. ---------------------------------------------------------
14. public class Plus extends AbstractCalculator implements ICalculator {
15.
16. 	@Override
17. 	public int calculate(String exp) {
18. 		int arrayInt[] = split(exp, "\\+");
19. 		return arrayInt[0] + arrayInt[1];
20. 	}
21. }
22. --------------------------------------------------------
23. public class AbstractCalculator {
24. 	public int[] split(String exp, String opt) {
25. 		String array[] = exp.split(opt);
26. 		int arrayInt[] = new int[2];
27. 		arrayInt[0] = Integer.parseInt(array[0]);
28. 		arrayInt[1] = Integer.parseInt(array[1]);
29. 		return arrayInt;
30. 	}
31. }
1. public class StrategyTest {
2. 		public static void main(String[] args) {
3. 			String exp = "2+8";
4. 			ICalculator cal = new Plus();
5. 			int result = cal.calculate(exp);
6. 			System.out.println(result);
7. 		}
8. }

7、观察者模式(Observer)

什么是观察者模式

一、
在这里插入图片描述
二、
在这里插入图片描述

三、
观察者模式很好理解,类似于邮件订阅和 RSS 订阅,当我们浏览一些博客或 wiki 时,经常会看到 RSS 图标,就这的意思是,当你订阅了该文章,如果后续有更新,会及时通知你。其实,简单来讲就一句话:当一个对象变化时,其它依赖该对象的对象都会收到通知,并且随着变化!对象之间是一种一对多的关系。

1. public interface Observer {
2. 		public void update();
3. }
4.
5. public class Observer1 implements Observer {
6. 		@Override
7. 		public void update() {
8. 			System.out.println("observer1 has received!");
9. 		}
10. }
11.
12. public class Observer2 implements Observer {
13. 	@Override
14. 	public void update() {
15. 		System.out.println("observer2 has received!");
16. 	}
17. }
18.
19. public interface Subject {
20. /*增加观察者*/
21. public void add(Observer observer);
22.
23. /*删除观察者*/
24. public void del(Observer observer);
25. /*通知所有的观察者*/

1. public void notifyObservers();
2.
3. /*自身的操作*/
4. public void operation();
5. }
6.
7. public abstract class AbstractSubject implements Subject {
8.
9. 		private Vector<Observer> vector = new Vector<Observer>();
10.
11. 	@Override
12. 	public void add(Observer observer) {
13. 		vector.add(observer);
14. 	}
15.
16. 	@Override
17. 	public void del(Observer observer) {
18. 		vector.remove(observer);
19. 	}
20.
21. 	@Override
22. 	public void notifyObservers() {
23. 		Enumeration<Observer> enumo = vector.elements();
24. 		while (enumo.hasMoreElements()) {
25. 			enumo.nextElement().update();
26. 		}
27. 	}
28. }
29.
30. public class MySubject extends AbstractSubject {
31.
32. 	@Override
33. 	public void operation() {
34. 		System.out.println("update self!");
35. 		notifyObservers();
36. 	}
37. }
38.
39. public class ObserverTest {
40. 	public static void main(String[] args) {
41. 		Subject sub = new MySubject();
42. 		sub.add(new Observer1());
43. 		sub.add(new Observer2());
44. 		sub.operation();
45. 	}
46. }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1) 优秀的程序应该是这样的:阅读时,感觉很优雅;新增功能时,感觉很轻松;运行时,感觉很快速,这就需要设计模式支撑。2) 设计模式包含了大量的编程思想,讲授和真正掌握并不容易,网上的设计模式课程不少,大多讲解的比较晦涩,没有真实的应用场景和框架源码支撑,学习后,只知其形,不知其神。就会造成这样结果: 知道各种设计模式,但是不知道怎么使用到真实项目。本课程针对上述问题,有针对性的进行了升级 (1) 授课方式采用 图解+框架源码分析的方式,让课程生动有趣好理解 (2) 系统全面的讲解了设计模式,包括 设计模式七大原则、UML类图-类的六大关系、23种设计模式及其分类,比如 单例模式的8种实现方式、工厂模式的3种实现方式、适配器模式的3种实现、代理模式的3种方式、深拷贝等3) 如果你想写出规范、漂亮的程序,就花时间来学习下设计模式吧课程内容和目标本课程是使用Java来讲解设计模式,考虑到设计模式比较抽象,授课采用 图解+框架源码分析的方式1) 内容包括: 设计模式七大原则(单一职责、接口隔离、依赖倒转、里氏替换、开闭原则、迪米特法则、合成复用)、UML类图(类的依赖、泛化和实现、类的关联、聚合和组合) 23种设计模式包括:创建型模式:单例模式(8种实现)、抽象工厂模式、原型模式、建造者模式、工厂模式。结构型模式:适配器模式(3种实现)、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式(3种实现)。行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式)2) 学习目标:通过学习,学员能掌握主流设计模式,规范编程风格,提高优化程序结构和效率的能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值