java 设计模式 常用21种
1.创造型:抽象工厂
- package com.seezoon.创建型.抽象工厂;
- /**
- * 抽象工厂
- * @author DF
- *工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,
- *必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?
- *就用到抽象工厂模式,创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,
- *不需要修改之前的代码
- */
- public class AbstractFactory {
- public static void main(String[] args) {
- IFactory factory = new ProductAFactory();
- IProduct product = factory.produce();
- product.productMethod();
- }
- }
- interface IFactory {
- public IProduct produce();
- }
- class ProductAFactory implements IFactory{
- @Override
- public IProduct produce() {
- return new ProductA();
- }
- }
- class ProductBFactory implements IFactory{
- @Override
- public IProduct produce() {
- return new ProductB();
- }
- }
- interface IProduct {
- public void productMethod();
- }
- class ProductA implements IProduct {
- @Override
- public void productMethod() {
- System.out.println("ProductA");
- }
- }
- class ProductB implements IProduct {
- @Override
- public void productMethod() {
- System.out.println("ProdectB");
- }
- }
- package com.seezoon.创建型.单例;
- import jdk.internal.dynalink.beans.StaticClass;
- /**
- * 简单单例模式(严格的单例模式一般情况不适用可自行科普。)
- * @author DF
- * 单例模式(Singleton)
- 单例对象(Singleton)是一种常用的设计模式。在Java应用中,单例对象能保证在一个JVM中,
- 该对象只有一个实例存在。这样的模式有几个好处:
- 1、某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销。
- 2、省去了new操作符,降低了系统内存的使用频率,减轻GC压力。
- 3、有些类如交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了。
- (比如一个军队出现了多个司令员同时指挥,肯定会乱成一团),所以只有使用单例模式,才能保证核心交易服务器独立控制整个流程。
- Singleton是一种创建型模式,指某个类采用Singleton模式,则在这个类被创建后,只可能产生一个实例供外部访问,并且提供一个全局的访问点。
- 核心知识点如下:
- (1) 将采用单例设计模式的类的构造方法私有化(采用private修饰)。
- (2) 在其内部产生该类的实例化对象,并将其封装成private static类型。
- (3) 定义一个静态方法返回该类的实例。
- */
- /**
- * 1.单例模式的实现:饱汉式,非线程安全
- * 优点是:写起来比较简单,当类SingletonTest被加载的时候,静态变量static的instance未被创建并分配内存空间,
- * 当getInstance方法第一次被调用时,初始化instance变量,并分配内存,因此在某些特定条件下会节约了内存;
- 缺点是:并发环境下很可能出现多个SingletonTest实例。
- * @author HP
- *
- */
- public class Singleton {
- /* 持有私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载 */
- private static Singleton instance = null;
- /* 私有构造方法,防止被实例化 */
- private Singleton() {
- }
- /* 静态工程方法,创建实例 */
- public static Singleton getInstance() {
- if (instance == null) {
- instance = new Singleton();
- }
- return instance;
- }
- }
- /**
- * 2.单例模式的实现:饿汉式,线程安全 但效率比较低
- * 优点是:写起来比较简单,而且不存在多线程同步问题,避免了synchronized所造成的性能问题;
- 缺点是:当类SingletonTest被加载的时候,会初始化static的instance,静态变量被创建并分配内存空间,
- 从这以后,这个static的instance对象便一直占着这段内存(即便你还没有用到这个实例),
- 当类被卸载时,静态变量被摧毁,并释放所占有的内存,因此在某些特定条件下会耗费内存。
- */
- /**public*/ class SingletonTest {
- // 定义一个私有的构造方法
- private SingletonTest() {
- }
- // 将自身的实例对象设置为一个属性,并加上Static和final修饰符
- private static final SingletonTest instance = new SingletonTest();
- // 静态方法返回该类的实例
- public static SingletonTest getInstancei() {
- return instance;
- }
- }
- package com.seezoon.创建型.工厂方法.多个工厂方法;
- /**
- * 多个工厂方法模式
- * 是对普通工厂方法模式的改进,在普通工厂方法模式中,
- * 如果传递的字符串出错,则不能正确创建对象,而多个工厂方法模式是提供多个工厂方法,分别创建对象
- * @author DF
- *
- */
- public class MutiFactoryMethod {
- public static void main(String[] args) {
- MutiFactory factory = new MutiFactory();
- IProduct product = factory.produceA();
- product.productMethod();
- }
- }
- class MutiFactory{
- public IProduct produceA(){
- return new ProductA();
- }
- public IProduct produceB(){
- return new ProductB();
- }
- }
- interface IProduct {
- public void productMethod();
- }
- class ProductA implements IProduct {
- @Override
- public void productMethod() {
- System.out.println("ProductA");
- }
- }
- class ProductB implements IProduct {
- @Override
- public void productMethod() {
- System.out.println("ProductB");
- }
- }
- package com.seezoon.创建型.工厂方法.静态工厂;
- /**
- * 静态工厂方法模式
- * 将多个工厂方法模式里的方法置为静态的,不需要创建实例,直接调用即可
- * @author DF
- *
- */
- public class StaticiFactoryMethod {
- public static void main(String[] args) {
- IProduct product = StaticFactory.produceA();
- product.productMethod();
- }
- }
- class StaticFactory{
- public static IProduct produceA(){
- return new ProductA();
- }
- public static IProduct produceB(){
- return new ProductB();
- }
- }
- interface IProduct {
- public void productMethod();
- }
- class ProductA implements IProduct {
- @Override
- public void productMethod() {
- System.out.println("ProductA");
- }
- }
- class ProductB implements IProduct {
- @Override
- public void productMethod() {
- System.out.println("ProductB");
- }
- }
- package com.seezoon.创建型.工厂方法.普通工厂模式;
- /**
- * 普通工厂方法比较常用
- * @author DF
- *
- */
- public class NormalFactoryMethod {
- public static void main(String[] args) {
- Factory factory= new Factory();
- IProduct product = factory.produce("A");
- product.productMethod();
- }
- }
- class Factory{
- /**
- * 一般可以做成配置 比如xml
- * @param product
- * @return
- */
- public IProduct produce(String product){
- if ("A".equals(product)) {
- return new ProductA();
- } else if ("B".equals(product)) {
- return new ProductB();
- } else {
- return null;
- }
- }
- }
- interface IProduct {
- public void productMethod();
- }
- class ProductA implements IProduct {
- @Override
- public void productMethod() {
- System.out.println("ProductA");
- }
- }
- class ProductB implements IProduct {
- @Override
- public void productMethod() {
- System.out.println("ProductB");
- }
- }
6.创造型:建造者
- package com.seezoon.创建型.建造者;
- /**
- * 建造者模式
- * @author DF
- * 工厂模式关注的是创建单个产品,而建造者模式则关注创建符合对象
- */
- public class Builder {
- public static void main(String []args){
- Director dir = new Director();
- dir.getProduct1().showProduct();
- dir.getProduct2().showProduct();
- }
- }
- class Director {
- private AbsBuild build = new Build();
- public Product getProduct1(){
- build.setProd("df",15);
- return build.getProduct();
- }
- public Product getProduct2(){
- build.setProd("df",20);
- return build.getProduct();
- }
- }
- abstract class AbsBuild {
- public abstract void setProd(String name,int num);
- public abstract Product getProduct();
- }
- class Build extends AbsBuild {
- Product product = new Product();
- @Override
- public void setProd(String name, int num) {
- //To change body of implemented methods use File | Settings | File Templates.
- product.setName(name);
- product.setNum(num);
- }
- @Override
- public Product getProduct() {
- return product;
- }
- }
- class Product {
- private String name;
- private int num;
- public void showProduct(){
- System.out.println("name :"+name);
- System.out.println("age:"+num);
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getNum() {
- return num;
- }
- public void setNum(int num) {
- this.num = num;
- }
- }
7.创造型:原型
- package com.seezoon.创建型.原型;
- import java.io.ByteArrayInputStream;
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.io.ObjectInputStream;
- import java.io.ObjectOutputStream;
- import java.io.Serializable;
- /**
- *
- * @author DF
- *原型模式虽然是创建型的模式,但是与工程模式没有关系,从名字即可看出,
- *该模式的思想就是将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象。
- *在Java中,复制对象是通过clone()实现的
- */
- public class Prototype implements Cloneable,Serializable{
- /**
- *
- */
- private static final long serialVersionUID = 1L;
- public void print(){
- System.out.println("hello Prototype !!!!!");
- }
- /**
- * 该做法为浅复制
- * 浅复制:将一个对象复制后,基本数据类型的变量都会重新创建,而引用类型,指向的还是原对象所指向的。
- */
- public Prototype clone() throws CloneNotSupportedException {
- Prototype proto = (Prototype) super.clone();
- return proto;
- }
- /**
- * 深复制
- * 深复制:将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的。
- * 简单来说,就是深复制进行了完全彻底的复制,而浅复制不彻底
- * @return
- * @throws IOException
- * @throws ClassNotFoundException
- */
- public Prototype deepClone() throws IOException, ClassNotFoundException {
- /* 写入当前对象的二进制流 */
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(bos);
- oos.writeObject(this);
- /* 读出二进制流产生的新对象 */
- ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
- ObjectInputStream ois = new ObjectInputStream(bis);
- Prototype prototype = (Prototype) ois.readObject();
- ois.close();
- bis.close();
- oos.close();
- bos.close();
- return prototype;
- }
- public static void main(String[] args) throws Exception {
- Prototype prototype = new Prototype();
- Prototype prototypeClone = prototype.clone();
- Prototype prototypeDeepClone = prototype.deepClone();
- prototypeClone.print();
- prototypeDeepClone.print();
- }
- }
8.结构型:代理
- package com.seezoon.结构型.代理;
- /**
- *
- * @author DF
- *其实每个模式名称就表明了该模式的作用,代理模式就是多一个代理类出来,
- *替原对象进行一些操作,比如我们在租房子的时候回去找中介,为什么呢?
- *因为你对该地区房屋的信息掌握的不够全面,希望找一个更熟悉的人去帮你做,此处的代理就是这个意思。再如我们有的时候打官司,
- *我们需要请律师,因为律师在法律方面有专长,可以替我们进行操作,表达我们的想法
- *
- *
- *代理模式的应用场景:
- 如果已有的方法在使用的时候需要对原有的方法进行改进,此时有两种办法:
- 1、修改原有的方法来适应。这样违反了“对扩展开放,对修改关闭”的原则。
- 2、就是采用一个代理类调用原有的方法,且对产生的结果进行控制。这种方法就是代理模式。
- 使用代理模式,可以将功能划分的更加清晰,有助于后期维护!
- */
- public class ProxySample {
- public static void main(String[] args) {
- Sourceable source = new Proxy();
- source.method();
- }
- }
- interface Sourceable {
- public void method();
- }
- class Source implements Sourceable {
- @Override
- public void method() {
- System.out.println("the original method!");
- }
- }
- class Proxy implements Sourceable {
- private Source source;
- public Proxy(){
- super();
- this.source = new Source();
- }
- @Override
- public void method() {
- before();
- source.method();
- atfer();
- }
- private void atfer() {
- System.out.println("after proxy!");
- }
- private void before() {
- System.out.println("before proxy!");
- }
- }
- package com.seezoon.结构型.桥接;
- /**
- *
- * @author DF
- *桥接模式就是把事物和其具体实现分开,使他们可以各自独立的变化。
- *桥接的用意是:将抽象化与实现化解耦,使得二者可以独立变化,像我们常用的JDBC桥DriverManager一样,
- *JDBC进行连接数据库的时候,在各个数据库之间进行切换,基本不需要动太多的代码,
- *甚至丝毫不用动,原因就是JDBC提供统一接口,
- *每个数据库提供各自的实现,用一个叫做数据库驱动的程序来桥接就行了
- *
- *
- *
- *通过对Bridge类的调用,实现了对接口Sourceable的实现类SourceSub1和SourceSub2的调用
- */
- public class BridgeSample {
- public static void main(String[] args) {
- Bridge bridge = new MyBridge();
- /*调用第一个对象*/
- Sourceable source1 = new SourceSub1();
- bridge.setSource(source1);
- bridge.method();
- /*调用第二个对象*/
- Sourceable source2 = new SourceSub2();
- bridge.setSource(source2);
- bridge.method();
- }
- }
- interface Sourceable {
- public void method();
- }
- class SourceSub1 implements Sourceable {
- @Override
- public void method() {
- System.out.println("this is the first sub!");
- }
- }
- class SourceSub2 implements Sourceable {
- @Override
- public void method() {
- System.out.println("this is the second sub!");
- }
- }
- abstract class Bridge {
- private Sourceable source;
- public void method(){
- source.method();
- }
- public Sourceable getSource() {
- return source;
- }
- public void setSource(Sourceable source) {
- this.source = source;
- }
- }
- class MyBridge extends Bridge {
- public void method(){
- getSource().method();
- }
- }
10.结构型:对象适配器
- package com.seezoon.结构型.适配器.对象适配器;
- /**
- * 对象适配器
- * @author DF
- *对象的适配器模式:当希望将一个对象转换成满足另一个新接口的对象时,可以创建一个Adapter类,持有原类的一个实例,
- *在Adapter类的方法中,调用实例的方法就行。
- */
- public class ObjectAdapter {
- public static void main(String[] args) {
- Source source = new Source();
- Adapter adapter = new Adapter(source);
- adapter.method1();
- adapter.method2();
- }
- }
- class Source {
- public void method1() {
- System.out.println("this is original method!");
- }
- }
- interface Targetable {
- /* 与原类中的方法相同 */
- public void method1();
- /* 新类的方法 */
- public void method2();
- }
- class Adapter implements Targetable {
- private Source source;
- public Adapter(Source source) {
- super();
- this.source = source;
- }
- @Override
- public void method2() {
- System.out.println("this is the targetable method!");
- }
- @Override
- public void method1() {
- source.method1();
- }
- }