常用设计模式


一、单例模式

主要解决一个全局使用的类频繁地创建与销毁。


1、恶汉模式:
  • 优点:没有加锁,执行效率会提高。
  • 缺点:类加载时就初始化,浪费内存。
public class Singleton{
    private static Singleton1 singleton = new Singleton();
    private Singleton(){}
    public static Singleton getInstance(){
        return singleton;
    }
}
2、懒汉模式:
  • 优点:第一次调用才初始化,避免内存浪费。
  • 缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。
public class Singleton{
    private static Singleton singleton;
    private Singleton(){}
    public static synchronized Singleton getInstance(){
        if(singleton == null) 
            singleton = new Singleton();
        return singleton;
    }
}
3、双锁模式:
public class Singleton{
    private static Singleton singleton;
    private Singleton(){}
    public static Singleton getInstance(){
        if(singleton == null){
            synchronized(Singleton.class){
                if(singleton == null){
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}
4、登记模式:
public class Singleton{  
    private static class SingletonHolder{  
    private static final Singleton INSTANCE = new Singleton();  
    }  
    private Singleton(){}  
    public static final Singleton getInstance(){  
    return SingletonHolder.INSTANCE;  
    }  
}

几种常见单例模式 - CSDN博客 https://blog.csdn.net/qq_33187881/article/details/78760182


二、工厂模式

主要解决接口选择的问题。


1、工厂模式
  • 简单工厂模式是由一个工厂对象根据收到的消息决定要创建哪一个类的对象实例。
  • 优点:在于工厂类中包含了必要的逻辑,根据客户需要的逻辑动态实例化相关的类。
//接口Shape.java
public interface Shape {
    public void draw(); 
}
//接口实现类Circle.java
public class Circle implements Shape {
    public void draw() {
        System.out.println("Inside Circle::draw() method.");
    }
}
//接口实现类Rectangle.java
public class Rectangle implements Shape {
    public void draw() {
        System.out.println("Inside Rectangle::draw() method.");
    }
}
//接口实现类Square.java
public class Square implements Shape {
    public void draw() {
        System.out.println("Inside Square::draw() method.");
    } 
}
//创建一个ShapeFactory工厂,生成基于给定信息的实体类的对象。
public class ShapeFactory {
    public Shape getShape(String type) {
        if ("circle".equals(type)) {
            return new Circle();
        } else if ("rectangle".equals(type)) {
            return new Rectangle();
        } else if ("square".equals(type)) {
            return new Square();
        } else {
            return null;
        }
    }   
}
2、工厂方法模式
  • 定义一个创建对象工厂接口,让子类决定实例化哪个类,将实际创建工作推迟到子类当中。
  • 工厂方法模式克服了简单工厂所违背开闭原则的缺点,又保持了封装对象创建过程的优点。
//构建一个ShapeFactory工厂接口
public interface ShapeFactory { 
    public Shape getShape();    
}
//构建一个CircleFactory工厂实现ShapeFactory接口
public class CircleFactory implements ShapeFactory {
    public Shape getShape() {
        return new Circle();
    } 
}
//构建一个RectangleFactory工厂实现ShapeFactory接口
public class RectangleFactory implements ShapeFactory {
    public Shape getShape() {
        return new Rectangle();
    }
}
//构建一个RectangleFactory工厂实现ShapeFactory接口
public class SquareFactory implements ShapeFactory {
    public Shape getShape() {
        return new Square();
    }
}
//工厂方法模式测试类FactoryMethodDemo
public class FactoryMethodDemo {
    public static void main(String[] args) {
        ShapeFactory circleFactory = new CircleFactory();
        circleFactory.getShape().draw();
        ShapeFactory rectangleFactory = new RectangleFactory();
        rectangleFactory.getShape().draw();
        ShapeFactory squareFactory = new SquareFactory();
        squareFactory.getShape().draw();
    }
 }
3、抽象工厂模式
  • 抽象工厂是围绕一个超级工厂创建其他工厂,该超级工厂又称为其他工厂的工厂。提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。
  • 当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
//构建一个Button接口
public interface Button {   
    public void processEvent(); 
}
//构建一个Text接口
public interface Text {
    public void getWholeText(); 
}
//构建一个LinuxButton类实现Button接口
public class LinuxButton implements Button {
    public void processEvent() {
        System.out.println("Inside LinuxButton::processEvent() method.");
    }
}
//构建一个WindowsButton类实现Button接口
public class WindowsButton implements Button {
    public void processEvent() {
        System.out.println("Inside WindowsButton::processEvent() method.");
    }
}
//构建一个LinuxText类实现Text接口
public class LinuxText implements Text {
    public void getWholeText() {
        System.out.println("Inside LinuxText::getWholeText() method.");
    }
}
//构建一个WindowsText类实现Text接口
public class WindowsText implements Text {
    public void getWholeText() {
        System.out.println("Inside WindowsText::getWholeText() method.");
    }
}
//构建一个抽象工厂AbstractFactory 接口
public interface AbstractFactory {  
    public Button createButton();   
    public Text createText(); 
}
//构建一个工厂LinuxFactory类实现AbstractFactory接口
public class LinuxFactory implements AbstractFactory {
    public Button createButton() {
        return new LinuxButton();
    }
    public Text createText() {
        return new LinuxText();
    }
}
//构建一个工厂WindowsFactory类实现AbstractFactory接口
public class WindowsFactory implements AbstractFactory {
    public Button createButton() {
        return new WindowsButton();
    }
    public Text createText() {
        return new WindowsText();
    } 
}
//抽象工厂测试类AbstractFactoryDemo
public class AbstractFactoryDemo {  
    public static void main(String[] args) {
        AbstractFactory linuxFactory = new LinuxFactory();
        linuxFactory.createButton().processEvent();
        linuxFactory.createText().getWholeText();
        AbstractFactory windowsFactory = new WindowsFactory();
        windowsFactory.createButton().processEvent();
        windowsFactory.createText().getWholeText();
    }
}

工厂模式https://blog.csdn.net/wfg18801733667/article/details/60954744


三、消费者生产者模式

主要解决多线程的问题。


1、wait() / notify()方法
@Data
public class Storage{
    private final int MAX_SIZE = 100;
    private LinkedList<Object> list = new LinkedList<Object>();
    public void produce(String producer) throws InterruptedException {
        synchronized (list){
            while (list.size() == MAX_SIZE){
                list.wait();
            }
            list.add(new Object());
            list.notifyAll();
        }
    }
    public void consume(String consumer) throws InterruptedException {
        synchronized (list){
            while (list.size()==0){
                list.wait();
            }
            list.remove();
            list.notifyAll();
        }
    }
}
2、await() / signal()方法
@Data
public class Storage {
    private final int MAX_SIZE = 100;
    private LinkedList<Object> list = new LinkedList<Object>();
    private final Lock lock = new ReentrantLock();
    private final Condition full = lock.newCondition();
    private final Condition empty = lock.newCondition();
    public void produce(String producer) throws InterruptedException {
        lock.lock();
        while (list.size() == MAX_SIZE) {
            full.await();
        }
        list.add(new Object());
        empty.signalAll();
        lock.unlock();
    }
    public void consume(String consumer) throws InterruptedException {
        lock.lock();
        while (list.size() == 0) {
            empty.await();
        }
        list.remove();
        full.signalAll();
        lock.unlock();
    }
}
3、put() / take()方法
@Data
public class Storage {
    private final int MAX_SIZE = 100;
    private LinkedBlockingQueue<Object> list = new LinkedBlockingQueue<Object>(100);
    public void produce(String producer) throws InterruptedException {
        if (list.size() == MAX_SIZE) {
        }
        list.put(new Object());
 }
    public void consume(String consumer) throws InterruptedException {
        if (list.size() == 0) {
        }
        list.take();
    }
}
4、Tset方法
public class Test {
    public static void main(String[] args) {
        Storage storage = new Storage();
        for (int i = 1; i < 6; i++) {
            int finalI = i;
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        storage.produce(String.format("生成者%d:", finalI));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
        for (int j = 1; j < 4; j++) {
            int finalJ = j;
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        storage.consume(String.format("消费者%d:", finalJ));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }
}
5、PipedIO
public class PipedIO {
    private PipedInputStream pis = new PipedInputStream();
    private PipedOutputStream pos = new PipedOutputStream();
    public static void main(String[] args) throws IOException {
        PipedIO pipedIO = new PipedIO();
        pipedIO.initThread();
    }
    private void initThread() throws IOException {
        pos.connect(pis);
        Thread input = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    while (true) {
                        pos.write(new Date().toString().getBytes());
                        Thread.sleep(1000);
                    }
                } catch (IOException | InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        Thread output = new Thread(new Runnable() {
            @Override
            public void run() {
                byte[] temp = new byte[1024];
                try {
                    int len;
                    while ((len = pis.read(temp)) != -1) {
                        Thread.sleep(1000);
                    }
                } catch (IOException | InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        input.start();
        output.start();
    }
}

生产者消费者模式-Java实现https://www.cnblogs.com/chentingk/p/6497107.html


四、代理模式

可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能.


1、静态代理:
//接口
public interface UserDao {
    void save();
}
//接口实现类
public class UserDaoImpl implements UserDao {
    public void save() {
        System.out.println("保存数据");
    }
}
//代理对象
public class UserDaoProxy implements UserDao {
    private UserDao target;
    public UserDaoProxy(UserDao target){
        this.target=target;
    }
    public void save() {
        System.out.println("开始事务");
        target.save();
        System.out.println("提交事务");
    }
}
//测试
public class Tset {
    public static void main(String[] args) {
        UserDaoImpl target = new UserDaoImpl();
        UserDaoProxy proxy = new UserDaoProxy(target);
        proxy.save();
    }
}
2、动态代理:
//代理工厂模式
public class ProxyFactory {
    private Object target;
    public ProxyFactory(Object target) {
        this.target = target;
    }
    public Object getProxyInstance() {
        return Proxy.newProxyInstance(
            target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            new InvocationHandler() {
                 @Override
                 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("开始事务2");
                    Object returnValue = method.invoke(target, args);
                    System.out.println("提交事务2");
                    return returnValue;
                 }
             }
        );
    }
}
//测试方法
public class Test {
    public static void main(String[] args) {
        UserDaoImpl target = new UserDao();
        System.out.println(target.getClass());
        UserDaoImpl proxy = (UserDaoImpl) new ProxyFactory(target).getProxyInstance();
        System.out.println(proxy.getClass());
        proxy.save();
    }
}
3、CGLIB代理:
//目标对象,没有实现任何接口
public class UserDao {
    public void save() {
        System.out.println("保存数据");
    }
}
//Cglib子类代理工厂
public class ProxyFactory implements MethodInterceptor{
    private Object target;
    public ProxyFactory(Object target) {
        this.target = target;
    }
    public Object getProxyInstance(){
        Enhancer en = new Enhancer();
        en.setSuperclass(target.getClass());
        en.setCallback(this);
        return en.create();
    }
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("开始事务...");
        Object returnValue = method.invoke(target, args);
        System.out.println("提交事务...");
        return returnValue;
    }
}
//测试
public class Test {
    public static void main(String[] args) {
        IUserDao target = new UserDao();
        UserDao proxy = (UserDao)new ProxyFactory(target).getProxyInstance();
        proxy.save();
    }
}

Java的三种代理模式 - 岑宇 - 博客园 https://www.cnblogs.com/cenyu/p/6289209.html


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值