java设计模式

一、设计模式分类

总的分为三大类:

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

2、结构型模式(七种):适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、亨元模式。

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

4、还有两类模式:并发型模式和线程池模式。

二、设计模式的六大原则

1、开闭原则(Open Close Principle)

开闭原则就是对扩展开发,对修改关闭;为了使程序扩展性好,不能修改原代码,易于维护和升级。需要使用接口和抽象类。

2、里氏换代原则(Liskov Substitution Principle)

里氏换代原则是面向对象设计的基本原则之一。任何基类出现的地方,子类一定可以出现。当子类可以替换掉基类,

程序不受影响时,基类才真正被复用,而子类也能在基类上增加新的行为。里氏换代原则是对实现抽象化的具体步骤规范。

3、依赖倒转原则(Dependence Inversion Principle)

针对接口编程,依赖于抽象而不是依赖于具体。

4、接口隔离原则(Interface Segregation Principle)

使用多个隔离接口,比使用单个接口要好,是为了降低类之间的耦合度。

5、迪米特法则(Demeter Principle)

迪米特法则也叫最少知道原则,一个实体应当减少与另一个实体发生相互作用,使得系统模块能够独立。

6、合成复用原则(Composite Reuse Principle)

尽量使用合成/聚合方式,而不是继承。

三、模式讲解

1、工厂模式分为三种:

1.1 普通工厂方法模式:建立一个工厂类,对实现了同一个接口的类进行实例创建。

1.2 多个工厂方法模式:是普通工厂的改进版,普通工厂如果传递的字符串出错,则不能创建工厂,而多个工厂方法是创建多个工厂,分别创建对象。

1.3 静态工厂方法模式:是工厂的改进版,将工厂方法设置为静态的,不需要创建实例,直接调用即可。

2、抽象工厂是工厂方法的升级,因为工厂方法有一个弊端,想要扩展程序,就需要对工厂进行修改;为此用到了抽象工厂,抽象工厂就是创建多个工厂类,

需要扩展程序时直接添加工厂即可。

总体来说,工厂方法模式适合:凡是出现了大量的产品需要创建,并有共同的接口时,通过工厂方法创建。

以上三种工厂方法模式,第一种如果传入的字符串有误,不能正确创建对象,第三种相对于第二种,不需要创建对象,所以选用第三种。

3、单例模式:单例模式的类必须保证只有一个实例存在。

单例模式还分为:懒汉式(只有外部对象第一次调用实例时才创建)、

饿汉式(加载类比较慢,运行时得到对象速度比较快);单例模式的好处:(1)某些类创建比较频繁,对于大型对象,

这是一笔很大的系统开销;(2)省去new操作符,降低系统内存使用频率,减少GC压力。

4、建造者模式(Builder):建造者模式就是将各种类集中起来管理,创建复合对象,复合对象就是指某个类有不同的属性,

建造者模式和工厂模式的区别就是:工厂模式关注的是创建单个类,而建造者模式是创建复合对象。

5、原型模式(Prototype): 原型模式虽然是创建型模式,但与工厂模式无关,原型模式就是将一个对象作为原型,

对其进行复制、克隆,产生一个新的对象,需要实现Cloneable接口,用clone()方法实现的( super.clone() );原型模式分为两种复制概念:浅复制和深复制。

1、浅复制:只会复制原有对象中的基本数据类型变量,而引用类型还是指向原有对象。

2、深复制:采用流的形式读取原对象的二进制输入,再写出二级制数据对应的对象。深复制会把原有对象中的数据类型全部复制,也就是完全彻底的复制。

6、适配器模式(Abapter):适配器模式就是将类的接口转换成调用者期望的接口,消除接口不匹配和不兼容问题。主要有三类:类适配器模式、对象适配器模式、接口适配器模式。

7、装饰模式(Decorator):装饰模式就是就是给对象增加新的功能并且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例。

8、代理模式(Proxy):代理模式就是用一个代理类调用原有的方法,且对产生的结果进行控制;比如在法院打官司时需要找律师,因为律师在法律方面比较专业,这就是代理。

9、外观模式(Facade):外观模式是为解决类与类之间依赖关系的,外观模式就是将类之间的关系放在一起,降低类与类之间的耦合度,并实现解耦作用,这就是外观模式。

10、桥连接模式(Bridge): 桥链接模式就是把事物和具体实现分开,使各模块各自独立化;与JDBC原理一样。JDBC原理就是有一个统一的接口,每种数据库实现接口即可。

11、组合模式:组合模式又叫 部分-整体模式,在处理树形结构的问题时比较方便,常用与树形结构,二叉树等。

12、亨元模式:亨元模式主要目的是实现对象的共享,即共享池。通常与工厂模式一起使用,比如连接数据库的JDBC连接池。适用于共享的对象,都有一些共有属性。

13、策略模式(strategy) 属于父类和子类的实现

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

设计一个接口,为一系列实现类提供统一方法,设计一个抽象类(可有可无,属于辅助类),提供辅助函数,使用算法的决定权在用户,该模式多用在算法中。

14、摸版方法模式(Template Method) 属于父类和子类的实现

摸版方法模式:一个抽象类中,有一个主方法,在定义多个方法,可以是抽象的,也可以是实际的方法,定义一个类,继承该抽象类,通过调用抽象类,实现子类的调用。

15、观察者模式(Observer) 属于两个类之间的实现

观察者模式:就是当一个对象变化时,依赖本对象的类都会收到通知,并且随着变化!对象之间是一对多的关系。

16、迭代子模式(Iterator) 属于两个类之间的实现

迭代器模式就是顺序访问聚集中的对象,第一就是遍历聚集的对象,第二就是对聚集的对象进行遍历访问。

17、责任链模式(Chain of Responsibility) 属于两个类之间的实现

责任链模式:有多个对象,每个对象持有对下一个对象的引用,请求在链上传递,直到某一个对象决定处理该请求。

但发送请求者并不知道那个对象会处理该请求。链接上的一个请求可以是一条链,一个树,一个环。

这个些需要我们自己去实现,在一个时刻,命令只允许由一个对象传给另一个对象,而不允许传给多个对象。

18、命令模式(Command) 属于两个类之间的实现

命令模式就是:命令的发出者和执行者之间解耦,实现请求和执行分开。

举个例子,比如司令员下令让士兵干件事情,口令传到士兵哪里并去执行,司令员只要结果,不关心执行过程。

19、备忘录模式(Memento) 类的状态

备忘录状态:就是要保存对象的某个状态,在适当的时候恢复对象。

20、状态模式(State) 类的状态

状态模式:当对象改变状态时,同时改变其行为,并且每个状态对应不同的操作。

21、访问者模式(Visitor) 通过中间类

访问者模式就是把数据结构和操作解耦合,使操作集合相对自由的演化。总的来说该模式添加数据结构很困难,添加操作很容易,并不会影响其它的操作效果。

22、中介者模式(Mediator) 通过中间类

中介者模式就是降低类与类之间的耦合,类与类的关系与调度交给中间类就行,类似有Spring的容器。

23、解释器模式(Interpreter) 通过中间类

解释器模式用来做各种各样的解释器,一般应用在OOP开发中的编译器,比如:正则表达式解释器等。

四、代码讲解

java 复制代码
1、工厂方法模式(Factory Method)
       工厂方法模式分为三种:
          1.1 普通工厂方法模式:建立一个工厂类,对实现了同一个接口的类进行实例创建。
            举例如下:举一个发送短信和发送邮件的例子

  //1.首先创建二者共同接口
    public interface Sender{
        public void send();
    }
    //2.创建邮件类
    public class MailSender implements Sender{
        @Override
        public void send() {
            System.out.println("发送邮件!");
        }
    }
    //3.创建短信类
    public class SmsSender implements Sender {
        @Override
        public void send() {
            System.out.println("发送短信!");
        }
    }
    //4.创建工厂类
    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();
        }  
    }

        输出结果:发送短信!

2、多个工厂方法模式:是普通工厂的改进版,普通工厂如果传递的字符串出错,则不能创建工厂,而多个工厂方法是创建多个工厂,分别创建对象。

 //创建多个工厂(对普通工厂的改进)
    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.produceSms();
            sender.send();
        }
    }
    输出结果:发送短信!

        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) {
            SendFactory factory = new SendFactory();
            sender.send();
        }
    }
    输出结果:发送短信!
     总体来说,工厂方法模式适合:凡是出现了大量的产品需要创建,并有共同的接口时,通过工厂方法创建。
      以上三种工厂方法模式,第一种如果传入的字符串有误,不能正确创建对象,第三种相对于第二种,不需要创建对象,所以选用第三种。

2、抽象工厂模式(Abstract Factory)
      抽象工厂是工厂方法的升级,因为工厂方法有一个弊端,想要扩展程序,就需要对工厂进行修改;
      为此用到了抽象工厂,抽象工厂就是创建多个工厂类,需要扩展程序时直接添加工厂即可。

  //1.首先创建二者共同接口
    public interface Sender{
        public void send();
    }
    //2.创建邮件实现类
    public class MailSender implements Sender{
        @Override
        public void send() {
            System.out.println("发送邮件!");
        }
    }
    //3.创建短信实现类
    public class SmsSender implements Sender {
        @Override
        public void send() {
            System.out.println("发送短信!");
        }
    }
    //4.创建工厂类
    public class SendMailFactory implements Provider{
        @Override
        public Sender produce() {
            return new MailSender();
        }
    }
    public class SendSmsFactory implements Provider{
        @Override
        public Sender produce() {
            return new SmsSender();
        }
    }

    //5.创建一个接口
    public interface Provider{
        public Sender produce();
    }

    //6.测试类
    public class Text{
        public static void main(String[] args) {
            Provider provider=new SendSmsFactory();
            Sender sender= provider.produce();
            sender.send();
        }
    }

3、单例模式(Singleton)
       单例模式:单例模式的类必须保证只有一个实例存在。单例模式还分为:懒汉式(只有外部对象第一次调用实例时才创建)、
       饿汉式(加载类比较慢,运行时得到对象速度比较快);单例模式的好处:(1)某些类创建比较频繁,对于大型对象,
       这是一笔很大的系统开销;(2)省去new操作符,降低系统内存使用频率,减少GC压力。             

 //1、饱汉式,线程不安全
    public class  Singleton{
        //持有私有静态实例,防止被引用,目的是实现延迟加载
        private static Singleton instance=null;
        //定义私有的构造方法
        private Singleton(){}
        
        //获取实例的方法
        public static Singleton getInstance(){
            if (instance==null){
                instance =new Singleton();
            }
            return instance;
        }
        //如果该对象被实例化,可以保证对象在实例化前后保持一致
        public Object readResolve(){
            return instance;
        }
    }
         //2、对该方法改进(添加synchronized(同步锁)关键字)
        //备注:synchronized是锁对象的,每次调用该方法都要给对象上锁,性能较低。
        public static synchronized Singleton getInstance(){
            if (instance==null){
                instance =new Singleton();
            }
            return instance;
        }
        
         //3、对该方法改进,将synchronized(同步锁)方法内部,只有instance为null,并创建对象时才加锁,性能有所提高
        public static  Singleton getInstance(){
            if (instance==null){
                synchronized(instance){
                    if (instance==null){
                        instance =new Singleton();
                    }
                }
            }
            return instance;
        }
        
    //4、改进单例模式最终结果(接近完美,但还有其它的实现方式)
    public class  Singleton{
        //持有私有静态实例,防止被引用,目的是实现延迟加载
        private static Singleton instance=null;sh
        //定义私有的构造方法
        private Singleton(){}
        //创建内部类工厂
        private static class SingletonFactory{
            private static Singleton instance=new Singleton();
        }
        //获取实例的方法
        //备注:该方法在第一次调用时是线程互斥的
        public static Singleton getInstance(){
            return SingletonFactory.instance;
        }
        //如果该对象被实例化,可以保证对象在实例化前后保持一致
        public Object readResolve(){
            return instance;
        }
    }
   4、建造者模式(Builder)
        建造者模式就是将各种类集中起来管理,创建复合对象,复合对象就是指某个类有不同的属性,
        建造者模式和工厂模式的区别就是:工厂模式关注的是创建单个类,而建造者模式是创建复合对象。

 //建造者模式
    public class Builder{
        private List<Sender> list=new ArrayList<Sender>();
            //发送邮件方法
        public void produceMailSender(int count){
            for (int i=0;i<count;i++){
                list.add(new MailSender());
            }
        }
            //发送短信方法
        public void produceSmsSender(int count){
            for (int i=0;i<count;i++){
                list.add(new SmsSender());
            }
        }
        
    }
    public class Test{
        public static void main(String[] args) {
            Builder builder=new Builder();
            builder.produceSmsSender(10);
        }
    }
5、原型模式(Prototype)
     原型模式虽然是创建型模式,但与工厂模式无关,原型模式就是将一个对象作为原型,对其进行复制、克隆,
     产生一个新的对象,需要实现Cloneable接口,用clone()方法实现的( super.clone() );
     原型模式分为两种复制概念:浅复制和深复制。
         1、浅复制:只会复制原有对象中的基本数据类型变量,而引用类型还是指向原有对象。
         2、深复制:采用流的形式读取原对象的二进制输入,再写出二级制数据对应的对象。深复制会把原有对象中的数据类型全部复制,也就是完全彻底的复制。

public class Prototype implements Cloneable,Serializable{
        private static final long serialVersionUID=1L;
        private String string;
        private SerializableObject obj;
        //浅复制,只复制原有对象的基本数据类型变量
       public Object clone() throws CloneNotSupportedException {
           Prototype prototype=(Prototype) super.clone();
           return prototype;
       }
       //深复制,用IO流复制所有属性
       public Object deeClone() throws IOException, ClassNotFoundException {
           //写入当前对象的二进制流
           ByteArrayOutputStream bos=new ByteArrayOutputStream();
           ObjectOutputStream oos=new ObjectOutputStream(bos);
           //读取二进制流产生对象
           ByteArrayInputStream bis =new ByteArrayInputStream(bos.toByteArray());
           ObjectInputStream ois=new ObjectInputStream(bis);
           return ois.readObject();
       }
       
       public String getString() {
           return string;
       }
       public void setString(String string) {
           this.string = string;
       }
       public SerializableObject getObj() {
           return obj;
       }
       public void setObj(SerializableObject obj) {
           this.obj = obj;
       }
   }
    class  SerializableObject implements Serializable{
        private static final long serialVersionUID=1L;
    }
6、适配器模式(Abapter)
         适配器模式就是将类的接口转换成调用者期望的接口,消除接口不匹配和不兼容问题。
          主要有三类:类适配器模式、对象适配器模式、接口适配器模式。

    //1、类适配器,有一个Source类,方法是method1(),目标接口是Targetable,通过Adapter类,将Source的功能扩展到Targetable
    //使用场景:当希望将一个类转换成满足另一个新接口的类时,可以使用类的适配器模式,创建一个新类,继承原有的类,实现新的接口即可。
    public class Source{
        public void method1(){
            System.out.print("这是第一个方法");
        }
    }
    public interface Targetable{
        //原类中的方法
        public void method1();
        //新类的方法
        public void method2();
    }
    //类适配器,添加新的方法
    public class Adapter extends Source implements Targetable{
        @Override
        public void method2() {
            System.out.print("这是新类的方法");
        }
    }
    //测试
    public class AdapterTest{
        public static void main(String[] args) {
            Targetable targetable=new Adapter();
            targetable.method1();
            targetable.method2();
        }
    }
    输出结果为:这是第一个方法
             这是新类的方法
//2、对象适配器,对象适配器与类适配器模式一样,只需要改类的源码即可
    //使用场景:希望将一个对象满足另一个新接口的对象时,创建一个类并持有原类的一个实例,在新类的方法中,调用实例的方法即可。
    public class Wrapper implements Targetable{
        private Source source;
        public Wrapper(Source source){
            super();
            this.source=source;
        }
        @Override
        public void method2() {
            System.out.println("这是新加的方法!");
        }
        @Override
        public void method1() {
            source.method1();
        }
    }
    public class AdapterTest{
        public static void main(String[] args) {
            Source source=new Source();
            Targetable target=new Wrapper(source);
            target.method1();
            target.method2();
        }
    }
  //3、接口适配器,创建一个abstract(抽象)类并实现接口,只需要把abstract(抽象)类提供给外部使用即可。
    //使用场景:当不希望实现接口中所有方法时,可以创建一个抽象类,实现所有方法,调用时只需继承抽象类即可。
    public interface Sourceable{
        public void method1();
        public void method2();
    }
    //创建抽象类
    public abstract class Wrappper implements Sourceable{
        public void method1(){}
        public void method2(){}
    }
    public class SourceSub extends  Wrappper{
        public void method1(){
            System.out.print("这是新的方法!");
        }
    }
    //测试类
    public class WrappperTest{
        public static void main(String[] args) {
            SourceSub ss=new SourceSub();
            ss.method1();
        }
    }
    输出结果:这是新的方法!
7、装饰模式(Decorator)
      装饰模式就是就是给对象增加新的功能并且是动态的,要求装饰对象和被装饰对象实现同一个接口,
         装饰对象持有被装饰对象的实例。

  //使用场景:需要扩展类的功能,动态的为对象添加功能,还不能动态撤销(继承做不到,因为继承是静态的,不能动态增删)。
    //缺点:产生过多相似对象,不易排错。
    public interface Sourceable{
        public void method();
    }
    //被装饰类
    public class Source implements Sourceable{
        @Override
        public void method() {
            System.out.println("被装饰类");
        }
    }
    //装饰类
    public class Decorator implements Sourceable{
        private Sourceable sourceable;
        public Decorator(Sourceable sourceable){
            super();
            this.sourceable=sourceable;
        }
        @Override
        public void method() {
            System.out.print("开始!");
            sourceable.method();
            System.out.print("结束!");
        }
    }
    //测试类
    public class DecoratorTest{
        public static void main(String[] args) {
            Sourceable sourceable=new Sourceable();
            Sourceable obj=new Decorator(sourceable);
            obj.method();
        }
    }
        输出结果:开始
                被装饰类
                结束
8、代理模式(Proxy)
       代理模式就是用一个代理类调用原有的方法,且对产生的结果进行控制;
       比如在法院打官司时需要找律师,因为律师在法律方面比较专业,这就是代理。

   //使用场景:需要对原有的方法进行改进,并需要对产生的结果进行控制,为此就需要代理。
    public interface Sourceable{
        public void method();
    }
        //实现类
    public class Soure implements Sourceable{
        @Override
        public void method() {
            System.out.print("这是接口的方法");
        }
    }
    //创建代理模式
    public class Proxy implements Sourceable{
        private Soure soure;
        public Proxy(){
            super();
            this.soure=new Soure();
        }
        @Override
        public void method() {
            atfer();
            soure.method();
            before();
        }
        private void atfer(){
            System.out.print("atfer proxy");
        }
        private void before(){
            System.out.print("before proxy");
        }
    }
    //测试类
    public class ProxyTest{
        public static void main(String[] args) {
            Sourceable soure=new Proxy();
            soure.method();
        }
    }
9、外观模式(Facade)
     外观模式是为解决类与类之间依赖关系的,外观模式就是将类之间的关系放在一起,
     降低类与类之间的耦合度,并实现解耦作用,这就是外观模式。
 public class CPU{
            public void startup(){
                System.out.print("CPU startup");
            }
            public void shutdown(){
                System.out.print("CPU shutdown");
            }
        }
        public class Memory{
            public void startup(){
                System.out.print("Memory startup");
            }
            public void shutdown(){
                System.out.print("Memory shutdown");
            }
        }
        public class Disk {
            public void startup(){
                System.out.print("Disk  startup");
            }
            public void shutdown(){
                System.out.print("Disk  shutdown");
            }
        }
        //外观模式
        public class Computer{
            private CPU cpu;
            private Memory memory;
            private Disk disk;
            public Computer(){
                cpu=new CPU();
                memory=new Memory();
                disk=new Disk();
            }
            public void startup(){
                System.out.print("start the  computer!");
                cpu.startup();
                memory.startup();
                disk.startup();
                System.out.print("start computer finished!");
            }
            public void shutdown(){
                System.out.print("begin to close the computer!");
                cpu.startup();
                memory.startup();
                disk.startup();
                System.out.print("computer closed!");
            }
        }
        //测试类
        public class User{
            public static void main(String[] args) {
                Computer computer=new Computer();
                computer.shutdown();
                computer.startup();
            }
        }
10、桥连接模式(Bridge)
      桥链接模式就是把事物和具体实现分开,使各模块各自独立化;
      与JDBC原理一样。JDBC原理就是有一个统一的接口,每种数据库实现接口即可。
//1.定义统一的接口
    public interface Sourceable{
        public void method();
    }
    //2.第一个实现类
    public class SourceSub1 implements Sourceable{
        @Override
        public void method() {
            System.out.print("第一个实现类");
        }
    }
    //3.第二个实现类
    public class SourceSub2 implements Sourceable{
        @Override
        public void method() {
            System.out.print("第二个实现类");
        }
    }
    //4.定义桥连接
    public abstract class Bridge{
        private Sourceable sourceable;
        public  void method(){
            sourceable.method();
        }
        public Sourceable getSourceable() {
            return sourceable;
        }
        public void setSourceable(Sourceable sourceable) {
            this.sourceable = sourceable;
        }
    }
    //5.
    public class MyBridge extends Bridge{
        public void method(){
            getSourceable().method();
        }
    }
    //6.测试类
    public class BridgeTest{
        public static void main(String[] args) {
            Bridge bridge=new MyBridge();
            //调用第一个对象
            SourceSub1 sourceSub1=new SourceSub1();
            bridge.setSourceable(sourceSub1);
            bridge.method();

            //调用第二个对象
            SourceSub2 sourceSub2=new SourceSub2();
            bridge.setSourceable(sourceSub2);
            bridge.method();
        }
    }
    输出结果:第一个实现类
            第二个实现类
11、组合模式(Composite)
       组合模式又叫 部分-整体模式,在处理树形结构的问题时比较方便,常用与树形结构,二叉树等。

//将多个对象组合一起进行操作,常用于树形结构,比如二叉树
public class TreeNode {
    private String name;
    private TreeNode parent;
    private Vector<TreeNode> children=new Vector<TreeNode>();
    //set和get方法省略


    //添加子节点
    public void add(TreeNode t){
        children.add(t);
    }
    //删除子节点
    public void remove(TreeNode t){
        children.remove(t);
    }
    //获取子节点
    public Enumeration<TreeNode> getChildren(){
        return children.elements();
    }
}
//测试类
public class Tree{
    TreeNode root=null;
    public Tree(String name){
        root=new TreeNode(name);
    }
    public static void main(String[] args) {
        Tree tree=new Tree("A");
        TreeNode t1=new TreeNode("B");
        TreeNode t2=new TreeNode("C");
        t1.add(t2);
        tree.root.add(t1);
        System.out.print("build the tree finished!");
    }
}
12、亨元模式(Flyweight)
 亨元模式主要目的是实现对象的共享,即共享池。通常与工厂模式一起使用,比如连接数据库的JDBC连接池。适用于共享的对象,都有一些共有属性。
                

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Vector;
//以JDBC连接池举例,该模式适用于 共享对象
public class ConnectionPool  {
    private Vector<Connection> pool;

    //共有属性
    private String url="jdbc:mysql://localhost:3306/test";
    private String username="root";
    private String password="root";
    private String driverClassName="com.mysql.jdbc.Driver";

    private int poolSize=100;
    private static ConnectionPool instance=null;
    Connection conn=null;

    //构造方法,做一些初始化工作
    private ConnectionPool(){
        pool=new Vector<Connection>(poolSize);
        for (int i = 0; i <poolSize ; i++) {
            try{
                Class.forName(driverClassName);
                conn= DriverManager.getConnection(url,username,password);
            }catch (ClassNotFoundException e){
                e.printStackTrace();
            }catch (SQLException e){
                e.printStackTrace();
            }
        }
    }
    //返回连接池
    public synchronized void release(){
        pool.add(conn);
    }
    //返回连接池中的一个数据库连接
    public synchronized Connection getConnection(){
        if (pool.size()>0){
            Connection conn=pool.get(0);
            pool.remove(conn);
            return conn;
        }else {
            return null;
        }
    }
}
13、策略模式(strategy)                  
         属于父类和子类的实现策略模式定义了一系列算法,并将每个算法封装起来,使其可以相互替换,
         且算法的变化不会影响到用户。设计一个接口,为一系列实现类提供统一方法,设计一个抽象类(可有可无,属于辅助类),
         提供辅助函数,使用算法的决定权在用户,该模式多用在算法中。

//该模式主要适用于算法封装,决定权在用户

//1.定义统一接口
public interface ICalculator{
    public int calculate(String exp);
}
//2.定义辅助类
public class AbstractCalculator  {
    public int[] split(String exp,String opt){
        String array[] = exp.split(opt);
        int arrayInt[] = new int[2];
        arrayInt[0] = Integer.parseInt(array[0]);
        arrayInt[1] = Integer.parseInt(array[1]);
        return arrayInt;
    }
}
//3.定义两个实现类
public class Plus extends AbstractCalculator implements ICalculator {
    @Override
    public int calculate(String exp) {
                int arrayInt[] = split(exp,"\\+");
                return arrayInt[0]+arrayInt[1];
    }
}
public class Minus extends AbstractCalculator implements ICalculator {
    @Override
    public int calculate(String exp) {
                int arrayInt[] = split(exp,"-");
               return arrayInt[0]-arrayInt[1];
    }
}
//测试类
public class StrategyTest{
    public static void main(String[] args) {
        String exp = "2+8";
        ICalculator cal = new Plus();
        int result = cal.calculate(exp);
        System.out.println(result);
    }
}
        输出结果为:10
14、摸版方法模式(Template Method)               
      属于父类和子类的实现摸版方法模式:一个抽象类中,有一个主方法,在定义多个方法,可以是抽象的,
      也可以是实际的方法,定义一个类,继承该抽象类,通过调用抽象类,实现子类的调用。

//1.定义一个抽象类
public abstract class AbstractCalculator {
    //主方法,实现对本类其他方法的调用
    public  final int calculate(String exp,String opt){
        int array[] =split(exp,opt);
        return calculate(array[0],array[1]);
    }
    //被子类重写的方法
    abstract public int calculate(int num1,int num2);

    public int[] split(String exp,String opt){
        String array[] = exp.split(opt);
        int arrayInt[] = new int[2];
        arrayInt[0] = Integer.parseInt(array[0]);
        arrayInt[1] = Integer.parseInt(array[1]);
        return arrayInt;
    }
}
//2.继承抽象类并重写方法
public class Plus extends AbstractCalculator{
    @Override
    public int calculate(int num1, int num2) {
        return num1+num2;
    }
}
//3.测试
public class StrategyTest {  
    public static void main(String[] args) {
        String exp = "8+8";
        AbstractCalculator cal = new Plus();
        int result = cal.calculate(exp, "\\+");
        System.out.println(result);
    }  
}  
15、观察者模式(Observer)                   
         属于两个类之间的实现
        观察者模式:就是当一个对象变化时,依赖本对象的类都会收到通知,并且随着变化!对象之间是一对多的关系。

import java.util.Enumeration;
import java.util.Vector;

//1.定义一个接口
public interface Observer {
    public void update();
}
//2.第一个实现类
public class Observer1 implements Observer {
    @Override
    public void update() {
         System.out.println("observer1 has received!");
    }
}
//3.第二个实现类
public class Observer2 implements Observer {
    @Override
    public void update() {
        System.out.println("observer2 has received!");
    }
}
//4.定义接口
public interface Subject{
    /*增加观察者*/
    public void add(Observer observer);
    /*删除观察者*/
    public void del(Observer observer);
    /*通知所有的观察者*/
    public void notifyObservers();
    /*自身的操作*/
    public void operation();
}
//5.定义监控对象列表类
public abstract class AbstractSubject implements Subject {
    private Vector<Observer> vector = new Vector<Observer>();
    @Override
    public void add(Observer observer) {
        vector.add(observer);
    }
    @Override
    public void del(Observer observer) {
        vector.remove(observer);
    }
    @Override
    public void notifyObservers() {
        Enumeration<Observer> enumo=vector.elements();
        while (enumo.hasMoreElements()){
            enumo.nextElement().update();
        }
    }
}
//6.定义主对象
public class MySubject extends AbstractSubject {
    @Override
    public void operation() {
        System.out.print("update self!");
        notifyObservers();
    }
}
//7.测试类
public class ObserverTest{
    public static void main(String[] args) {
        Subject sub=new MySubject();
        sub.add(new Observer1());
        sub.add(new Observer2());
        sub.notifyObservers();
    }
}
输出: update self!
      observer1 has received!
      observer2 has received!

16、迭代子模式(Iterator)   属于两个类之间的实现
      迭代器模式就是顺序访问聚集中的对象,第一就是遍历聚集的对象,第二就是对聚集的对象进行遍历访问。

//模拟集合类的过程
//1.定义操作集合类的接口
public interface Collection {
    public Iterator iterator();
    //取集合元素
    public Object get(int i);
    //取大小
    public int size();
}
//2.定义迭代遍历集合类的接口
public interface Iterator{
    //前移
    public Object previous();
    //后移
    public Object next();
    public boolean hasNext();
    //取最后一个元素
    public Object first();
}
//3.实现操作集合类的接口
public class MyCollection implements Collection{
    public String string[]={"A","B","C","D","E"};
    @Override
    public Iterator iterator() {
        return new MyIterator(this);
    }

    @Override
    public Object get(int i) {
        return string[i];
    }

    @Override
    public int size() {
        return string.length;
    }
}
//4.实现迭代遍历集合的接口
public class MyIterator implements Iterator{
    private Collection collection;
    private int pos=-1;
    public MyIterator(Collection collection){
        this.collection=collection;
    }
    @Override
    public Object previous() {
        if (pos>0){
            pos--;
        }
        return collection.get(pos);
    }
    @Override
    public Object next() {
        if (pos<collection.size()-1){
            pos++;
        }
        return collection.get(pos);
    }
    @Override
    public boolean hasNext() {
        if (pos<collection.size()-1){
            return true;
        }else {
            return false;
        }
    }
    @Override
    public Object first() {
        pos=0;
        return collection.get(pos);
    }
}
//测试
public class Test{
    public static void main(String[] args) {
        Collection collection=new MyCollection();
        Iterator it=collection.iterator();
        while (it.hasNext()){
            System.out.print(it.next());
        }
    }
}
    //打印结果:A B C D E
17、责任链模式(Chain of Responsibility)   属于两个类之间的实现
     责任链模式:有多个对象,每个对象持有对下一个对象的引用,请求在链上传递,直到某一个对象决定处理该请求。
     但发送请求者并不知道那个对象会处理该请求。链接上的一个请求可以是一条链,一个树,一个环。
     这个些需要我们自己去实现,在一个时刻,命令只允许由一个对象传给另一个对象,而不允许传给多个对象。

    //1.创建一个设置和修改引用对象的核心接口
public interface Handler{
    public void operator();
}
//2.创建私有的方法类
public abstract class AbstractHandler{
    private Handler handler;
    public Handler getHandler() {
        return handler;
    }
    public void setHandler(Handler handler) {
        this.handler = handler;
    }
}
//3.创建实现核心接口的类
public class MyHandler extends AbstractHandler implements Handler{

    private String name;
    public MyHandler(String name){
        this.name=name;
    }
    @Override
    public void operator() {
        System.out.print(name+"deal!");
        if (getHandler() !=null){
            getHandler().operator();
        }
    }
}
//测试类
public class Test{
    public static void main(String[] args) {
        MyHandler h1 = new MyHandler("h1");
        MyHandler h2 = new MyHandler("h2");
        MyHandler h3 = new MyHandler("h3");

        h1.setHandler(h2);
        h2.setHandler(h3);

        h1.operator();
    }
}

        //输出:  h1deal!
                h2deal!
                h3deal!
 18、命令模式(Command)   属于两个类之间的实现
        命令模式就是:命令的发出者和执行者之间解耦,实现请求和执行分开。
        举个例子,比如司令员下令让士兵干件事情,口令传到士兵哪里并去执行,司令员只要结果,不关心执行过程。

 //1.定义命令方法的接口
    public interface  Command{
        public  void  exe();
    }
    //2.实现命令方法接口的实现类(核心类)
    public class MyCommand implements  Command{
        private  Recciver recciver;
        public MyCommand(Recciver recciver){
            this.recciver=recciver;
        }
        @Override
        public void exe() {
            recciver.action();
        }
    }
    //3.创建士兵类
    public class Recciver{
        public  void action(){
            System.out.print("士兵执行命令!");
        }
    }
    //4.创建司令员类
    public class Invoker{
        private  Command command;
        public Invoker(Command command){
            this.command=command;
        }
        public void adtion(){
            System.out.print("司令员发出命令!");
        }
    }
    //测试类
    public class  Test{
        public static void main(String[] args) {
            Recciver recciver=new Recciver();
            Command cmd=new MyCommand(recciver);
            Invoker invoker=new Invoker(cmd);
            invoker.adtion();
        }
    }
        //输出:士兵执行命令!
19、备忘录模式(Memento)         类的状态
        备忘录状态:就是要保存对象的某个状态,在适当的时候恢复对象。

//1.创建原始类
    public class Original {
        private String value;  //需要保存的属性

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }

        public Original(String value) {
            this.value = value;
        }

        //创建备忘录类
        public Memento creatememento() {
            return new Memento(value);
        }
    
        public void restoreMemento(Memento memento) {
            this.value = memento.getValue();
        }
    }
       //2.创建备忘录类
    public class Memento{
            private String value;
            public Memento(String value){
                this.value=value;
            }
           public String getValue() { return value;}
           public void setValue(String value) {this.value = value;}
       }
       //3.创建存储备忘录类
    public class Storage{
           private Memento memento;
           public Storage(Memento memento){
               this.memento=memento;
           }
           public Memento getMemento() {return memento; }
           public void setMemento(Memento memento) {this.memento = memento;}
       }
       //测试类
    public class Test{
           public static void main(String[] args) {
               //创建原始类
               Original original=new Original("agg");
               //创建备忘录类
               Storage storage=new Storage(original.creatememento());
               //修改原始类状态
               System.out.print("初始化状态为:"+original.getValue());
               original.setValue("niu");
               System.out.print("修改后的状态为:"+original.getValue());
               //恢复原始类状态
               original.restoreMemento(storage.getMemento());
               System.out.print("恢复后的状态为:"+original.getValue());
           }
       }
       // 输出结果为:初始状态为:egg
                    修改后的状态为:niu
                    恢复后的状态为:egg
 20、状态模式(State)  类的状态
     状态模式:当对象改变状态时,同时改变其行为,并且每个状态对应不同的操作。

 //1.创建状态的核心类
    public class State{
        private String value;
        public String getValue() {return value;}
        public void setValue(String value) {this.value = value;}
        public void method1(){System.out.print("execute the first opt!");}
        public void method2(){System.out.print("execute the second opt!");}
    }
    //2.创建状态模式的切换类
    public class Context{
        private State state;
        public Context(State state){this.state=state;}
        public State getState() {return state;}
        public void setState(State state) {this.state = state;}
        public  void method(){
            if (state.getValue().equals("state1")){
                state.method1();
            }else if (state.getValue().equals("state2")){
                state.method2();
            }
        }
    }
    //测试类
    public class Test{
        public static void main(String[] args) {
            State state=new State();
            Context context=new Context(state);
            //设置第一种状态
            state.setValue("state1");
            context.method();
            //设置第二种状态
            state.setValue("state2");
            context.method();
        }
    }
            //输出结果:execute the first opt!
                      execute the second opt!
21、访问者模式(Visitor) 通过中间类
     访问者模式就是把数据结构和操作解耦合,使操作集合相对自由的演化。总的来说该模式添加数据结构很困难,
     添加操作很容易,并不会影响其它的操作效果。

                

 //1创建存放要访问的对象接口
    public interface Visitor{
        public void visit(Subject sub);
    }

    //2.创建实现要访问对象接口的实现类
    public class MyVisitor implements Visitor{
        @Override
        public void visit(Subject sub) {
            System.out.print("visit the subject:"+sub.getSubject());
        }
    }
    //3.创建访问的对象接口
    public interface Subject{
        //接受将要访问它的对象
        public void accept(Visitor visitor);
        //获取将要被访问的属性
        public String getSubject();
    }
    //4.创建实现访问对象的实现类
    public class MySubject implements Subject{
        @Override
        public void accept(Visitor visitor) {
            visitor.visit(this);
        }
        @Override
        public String getSubject() {
            return "love";
        }
    }
    //测试类
    public class Test{
        public static void main(String[] args) {
            Visitor visitor=new MyVisitor();
            Subject sub=new MySubject();
            sub.accept(visitor);
        }
    }
    //输出:visit the subject:love 
   22、中介者模式(Mediator)  通过中间类
    中介者模式就是降低类与类之间的耦合,类与类的关系与调度交给中间类就行,类似有Spring的容器。

 //1.创建中间类的接口
    public interface Mediator{
        public void createMediator();
        public void workAll();
    }
    //2.创建中间类的实现类
    public class MyMediator implements Mediator{
        private User user1;
        private User user2;
        public User getUser1(){return user1;}
        public User getUser2(){return user2;}
        @Override
        public void createMediator() {
            user1=new User1(this);
            user2=new User2(this);
        }
        @Override
        public void workAll() {
            user1.work();
            user2.work();
        }
    }
    //3.创建私有的类
    public abstract class User{
        private Mediator mediator;
        public Mediator getMediator(){return mediator;}
        public User(Mediator mediator){
            this.mediator=mediator;
        }
        public abstract void work();
    }
    //4.创建私有类的继承类
    public class User1 extends User{
        public User1(Mediator mediator){super(mediator);}

        @Override
        public void work() {
            System.out.print("执行user1类!");
        }
    }
    //5.创建私有类的继承类
    public class User2 extends User{
        public User2(Mediator mediator){super(mediator);}

        @Override
        public void work() {
            System.out.print("执行user2类!");
        }
    }
    //测试类
    public class Test{
        public static void main(String[] args) {
            Mediator mediator=new MyMediator();
            mediator.createMediator();
            mediator.workAll();
        }
    }
            //输出:执行user1类!
                    执行user2类!
  23、解释器模式(Interpreter) 通过中间类
     解释器模式用来做各种各样的解释器,一般应用在OOP开发中的编译器,比如:正则表达式解释器等。

  //.创建计算  的接口
    public interface Expression{
        public int interpret(Context context);
    }
    //2.创建   实现计算类
    public  class Plus implements Expression{
        @Override
        public int interpret(Context context) {
            return context.num1+context.num2;
        }
    }
    //3.创建   实现计算类
    public  class Minus implements Expression{
        @Override
        public int interpret(Context context) {
            return context.num1-context.num2;
        }
    }
    //4.创建上下文环境类
    public  class Context{
        private int num1;
        private int num2;
        public Context(int num1,int num2){
            this.num1=num1;
            this.num2=num2;
        }
        //get和set方法省略
    }
    //测试类
    public class  Text{
        public static void main(String[] args) {
            //计算9+2-8的值
            int result=new Minus().interpret((new Context(new Plus().interpret(new Context(9,2)),8)));
            System.out.print(result);
        }
    }
            //输出结果:3

110.生产者消费者?
    答:用阻塞队列BlockingQueue的实现,
    阻塞有两种情况:1)当队列满了的时候进行入队列操作;2)当队列空了的时候进行出队列操作;
    import java.util.concurrent.ArrayBlockingQueue;
    import java.util.concurrent.BlockingQueue;
    public class Test3 {
        private static Integer count = 0;
        //创建一个阻塞队列
        final BlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
        public static void main(String[] args) {
            Test3 test3 = new Test3();
            new Thread(test3.new Producer()).start();
            new Thread(test3.new Consumer()).start();
            new Thread(test3.new Producer()).start();
            new Thread(test3.new Consumer()).start();
        }
        class Producer implements Runnable { //生产者
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    try {
                        Thread.sleep(3000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    try {
                        blockingQueue.put(1);
                        count++;
                        System.out.println(Thread.currentThread().getName()
                                + "生产者生产,目前总共有" + count);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        class Consumer implements Runnable { 消费者
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e1) {
                        e1.printStackTrace();
                    }
                    try {
                        blockingQueue.take();
                        count--;
                        System.out.println(Thread.currentThread().getName()
                                + "消费者消费,目前总共有" + count);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
相关推荐
言慢行善3 小时前
sqlserver模糊查询问题
java·数据库·sqlserver
专吃海绵宝宝菠萝屋的派大星3 小时前
使用Dify对接自己开发的mcp
java·服务器·前端
大数据新鸟4 小时前
操作系统之虚拟内存
java·服务器·网络
Tong Z4 小时前
常见的限流算法和实现原理
java·开发语言
凭君语未可4 小时前
Java 中的实现类是什么
java·开发语言
He少年4 小时前
【基础知识、Skill、Rules和MCP案例介绍】
java·前端·python
克里斯蒂亚诺更新4 小时前
myeclipse的pojie
java·ide·myeclipse
迷藏4944 小时前
**eBPF实战进阶:从零构建网络流量监控与过滤系统**在现代云原生架构中,**网络可观测性**和**安全隔离**已成为
java·网络·python·云原生·架构
迷藏4944 小时前
**发散创新:基于Solid协议的Web3.0去中心化身份认证系统实战解析**在Web3.
java·python·web3·去中心化·区块链
qq_433502184 小时前
Codex cli 飞书文档创建进阶实用命令 + Skill 创建&使用 小白完整教程
java·前端·飞书