Java实现常见设计模式

1. 工厂模式

工厂模式包括简单(静态)工厂模式、工厂方法和抽象工厂模式。

简单工厂模式:

一般为传进具体的实现类的类名创建实例

public Inteface Sender {
    void send();
}
public Class MailSender implements Sender {
    void send() {
        System.out.printLn("send mail");
    }
}
public Class SmsSender implements Sender {
    void send() {
        System.out.printLn("send sms");
    }
}
// 创建实例的简单工厂
public Class SenderFactory {
    public static Sender getNewSender(String type) {
        if ("MailSender".equals(type) {
            teturn new MailSender();
        }
        if ("SmsSender".equals(type) {
            teturn new SmsSender();
        }
        return null;
    }
}

工厂方法:

定义一个抽象工厂,继承该抽象工厂的具体工厂生产具体某个产品

public inteface Sender {
    void send();
}
public class MailSender implements Sender {
    void send() {
        System.out.printLn("send mail");
    }
}
public class SmsSender implements Sender {
    void send() {
        System.out.printLn("send sms");
    }
}
// 定义一个抽象工厂
public abstrct class AbsFactory {
    public Sender getNewSender();
}
// 具体工厂的工厂方法
public MaiSenderFacotry extends AbsFactory {
    public Sender getNewSender() {
        return new MailSender();
    }
}
public SmsSenderFacotry extends AbsFactory {
    public Sender getNewSender() {
        return new SmsSender ();
    }
}

抽象工厂模式:

也是定义一个公共的工厂接口,不过该接口是定义了多个实现同个产品簇但不同产品类的方法。

public interface Wheel {
}
public interface Engine {
}
public class implements BMWWheel {
}
public class implements BMWEngine {
}
public class implements BenzWheel {
}
public class implements BenzEngine {
}
// 抽象工厂接口
public interface CarFactory {
    Wheel getNewWheel();
    Engine getNewEngine();
}
public class BMWCarFactory implements CarFactory{
    public Wheel getNewWheel() {
        return new BMWWheel();
    }
    public Engine getNewEngine () {
        return new BMWEngine ();
    }
}
public class BenzCarFactory implements CarFactory{
    public Wheel getNewWheel() {
        return new BenzWheel();
    }
    public Engine getNewEngine () {
        return new BenzEngine ();
    }
}

2. 单例模式

从加载时机分为饿汉式、懒汉式,从线程安全分为线程安全和线程不安全

饿汉式:

public class Singleton {
    private static final Singleton instance = new Singleton();
    private Singleton() {}
    public static Singleton getInstance() {
        return instance
    }
}

懒汉式:

public class Singleton {
    private static Singleton instance = null;
    private Singleton() {}
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

显然上面两个方式都是线程不安全的,下面给出线程安全的常见定义方式

双重检查机制:

public class Singleton {
    private static Singleton instance = null;
    private Singleton() {}
    public static Singleton getInstance() {
        synchronize(Singleton.class) {
            if (instance == null) {
                synchronize(Singleton.class) {
                    if (instance == null) {
                        instance = new Singleton();
                    }
                }
            }
        }
        return instance;
    }
}

内部类(基于类的加载机制):

public class Singleton {
    
    private Singleton(){}

    private static class Inner {
		static SingletonByInnerClass instance = new SingletonByInnerClass();	
		static SingletonByInnerClass getInstance() {
			return instance;
		}
	}

    public static Singleton getInstance() {
        return Inner.getInstance();
    }
    
}

3. 建造者模式

可以理解为使用建造者为要构建的对象添加相应的属性值后返回建造者,最后通过建造者的建造方法将构建对象创建出来。

Lombak 包里的@Builder的作用就是典型的建造者模式。

4. 原型模式

可以理解为每次需要一个对象实例都是重新创建一个实例,可以通过new、浅复制和深复制等方式创建

浅复制: 将一个对象复制后,基本数据类型的变量都会重新创建,而引用类型,指向的还是原对象所指向的。

深复制: 将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的。简单来说,就是深复制进行了完全彻底的复制,而浅复制不彻底。

//浅复制,Object里的实例方法clone()默认就是浅复制
public Object clone() throws CloneNotSupportedException { 
    Prototype proto = (Prototype) super.clone(); 
    return proto; 
}

/* 深复制实现示例 */ 
public Object 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); 
    return ois.readObject(); 
}

5. 适配器模式

当希望一个对象实例可以转换到某个适配的接口上,可以创建一个Wrapper类,实现适配接口并且持有所需要的对象实例。

// Targetable 为适配器接口
public class Wrapper implements Targetable {
    // 需要的对象实例
    private Source source;
    public Wrapper(Source source){ 
        super(); 
        this.source = source;
    } 
    @Override public void method2() { 
        System.out.println("this is the targetable method!"); 
    }
    @Override public void method1() { 
        source.method1(); 
    } 
}

6. 装饰器模式

装饰器模式就是给对象添加新的功能或特性,需要实现共同的接口,装饰对象持有被装饰对象。

public interface Sourceable { 
    public void method(); 
}

public class Source implements Sourceable { 
    @Override 
    public void method() { 
        System.out.println("the original method!"); 
    } 
}

public class Decorator implements Sourceable {
    private Sourceable source;
    public Decorator(Sourceable source){ 
        super(); 
        this.source = source; 
    } 
    @Override 
    public void method() { 
        System.out.println("before decorator!"); 
        source.method(); 
        System.out.println("after decorator!"); 
    } 
}

7. 代理模式

给对象一个代理对象,代理对象控制该对象的使用。

静态代理:

public interface Sourceable { 
    public void method(); 
}

public class Source implements Sourceable { 
    @Override 
    public void method() { 
        System.out.println("the original method!"); 
    } 
}

public class Proxy implements Sourceable {
    private Sourceable source;
    public Proxy(Sourceable source){ 
        super(); 
        this.source = source; 
    } 
    @Override 
    public void method() { 
        System.out.println("before proxy!"); 
        source.method(); 
        System.out.println("after proxy!"); 
    } 
}

装饰器和静态代理的实现模式相同,但装饰器模式强调对原对象的功能增强,静态代理强调对原对象的使用的一种控制过程。

JDK动态代理

IService proxy = (Service) Proxy.newProxyInstance(Service.class.getClassLoader(),     
    Service.class.getInterfaces(), new InvocationHandler() {
			
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws     
    Throwable {
	    return method.invoke(service, args);
	}
});

cglib动态代理

class CglibProxy implements MethodInterceptor {

	private Object beProxyObj;
	
	public Object proxy(Object obj) {
		this.beProxyObj = obj;
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(obj.getClass());
		enhancer.setCallback(this);
		return enhancer.create();
	}
	
	@Override
	public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
		System.out.println("cglib 的预处理 from " + this);
		arg3.invoke(beProxyObj, arg2);
		System.out.println("cglib 的后置处理 from " + this);
		return null;
	}
	
}

8. 外观模式

外观模式的使用是为了减少类与类之间的依赖复杂度或者说是耦合度,一般是将多个通用的组件封装到所谓的外观类(facade)中,由这个外观类统一暴露方法。

9. 桥接模式

就是将抽象与实现分开,使得他们可以独立变化。例如JDBC就是使用的桥接模式。

10. 组合模式

将多个对象组合在一起使用,我们所用的集合,包括二叉树等就是组合模式。

11. 享元模式

享元模式是为了实现对象的共享,这样可以减少对象的数量并减少内存的开销,常常与工厂模式一起使用。

12. 策略模式

定义一系列的算法,并将算法封装起来,算法之间可以相互替换,但不会影响到调用者,调用者只需决定调用哪个算法即可。

13. 模板方法模式

实现方式一般为父类即抽象类定义了一个公用的逻辑顺序,而定义的逻辑里会调用由子类实现的方法,将具体实现延迟到子类中,方便扩展。

14. 观察者模式

常用的场景即使订阅,当通知服务的信息产生变化时,接受方便可收到新的消息,一般为一对多的关系。

15. 迭代子模式

定义一个迭代器,使用这个迭代器遍历集合中的每一个元素,java 中 实现了java.util.Collection接口的集合类都有相应的迭代器。

16. 责任链模式

有多个对象,它们的关系时一个对象持有另一个对象,形成一条链。请求会在这个责任链中传递,直到某个对象处理这个请求,

这样调用方并不知道具体哪个对象处理了这个请求,实现请求的动态处理。

17. 命令模式

发起一个命令,系统根据这个命令响应具体的结果。这样命令发起人不需要知道命令的具体实现。

18. 备忘录模式

备忘录类保存备忘数据,供调用方在下次访问时查看。

19. 状态模式

对象根据不同的状态产生不同的行为,其他对象也可以知道该对象的状态。

20. 访问者模式

略。

21. 中介者模式

略。

22. 解释器模式

略。

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值