常见的几种设计模式

  1. 设计模式:
    1. 单例模式:

应用场景:如果希望在系统中某个类的实例只存在一个,并且提供一个访问他的全 局访问点。

写法:

饿汉单例(在类加载的时候就完成了初始化,所以类加载比较慢,但是获取对象的速度很快):

public class Singleton {
	//饿汉单例模式
    //在类加载时就完成了初始化,所以类加载较慢,但获取对象的速度快
    
    private static Singleton instance = new Singleton();//静态私有成员,已初始化
    
    private Singleton() 
    {
        //私有构造函数
    }
    
    public static Singleton getInstance()    //静态,不用同步(类加载时已初始化,不会有多线程的问题)
    {
        return instance;
    }
}
懒汉式:
package leecodeTest;

public class Singleton {
	//懒汉式单例模式
    //比较懒,在类加载时,不创建实例,因此类加载速度快,但运行时获取对象的速度慢
    
    
    private static Singleton intance = null;//静态私用成员,没有初始化
    
    private Singleton()
    {
        //私有构造函数
    }
    
    public static synchronized Singleton getInstance()    //静态,同步,公开访问点
    {
        if(intance == null)
        {
            intance = new Singleton();
        }
        return intance;
    }
}
    1. 工厂设计模式

普通工厂模式(通过建立一个工厂类,对实现同一接口的一些类进行实例的创 建):

public interface Sender {
	void send();
}
public class MailSender implements Sender{

	@Override
	public void send() {
		// TODO Auto-generated method stub
		System.out.println("This is mail sender...");
	}
}
public class SmsSender implements Sender{

	@Override
	public void send() {
		// TODO Auto-generated method stub
		System.out.println("This is sms sender...");
	}
}
public class FactoryPattern {
	public static void main(String[] args) {
		Sender sender=produce("mail");
		sender.send();
	}
	public static Sender produce(String str) {
		
		if ("main".equals(str)) {
			return new MailSender();
		}else if ("sms".equals(str)) {
            return new SmsSender();
        } else {
            System.out.println("输入错误...");
            return null;
        }
	}
}

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

public interface Sender {
	void send();
}
public class MailSender implements Sender{

	@Override
	public void send() {
		// TODO Auto-generated method stub
		System.out.println("This is mail sender...");
	}
}
public class SmsSender implements Sender{

	@Override
	public void send() {
		// TODO Auto-generated method stub
		System.out.println("This is sms sender...");
	}
}
public class SendFactory {
	public Sender produceMail() {
		return new MailSender();
	}
	public Sender produceSms() {
		return new SmsSender();
	}
}
public class FactoryPattern {
	public static void main(String[] args) {
		SendFactory sendFactory=new SendFactory();
		Sender sender=sendFactory.produceMail();
		sender.send();
	}
	
}

静态工厂模式:

public interface Sender {
	void send();
}
public class MailSender implements Sender{

	@Override
	public void send() {
		// TODO Auto-generated method stub
		System.out.println("This is mail sender...");
	}
}
public class SmsSender implements Sender{

	@Override
	public void send() {
		// TODO Auto-generated method stub
		System.out.println("This is sms sender...");
	}
}
public class SendFactory {
	public static Sender produceMail() {
		return new MailSender();
	}
	public static Sender produceSms() {
		return new SmsSender();
	}
}
public static void main(String[] args) {
		Sender sender=SendFactory.produceMail();
		sender.send();
	}

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

public interface Provider {
	Sender produce();
}
public interface Sender {
	void send();
}
public class SmsSender implements Sender{

	@Override
	public void send() {
		// TODO Auto-generated method stub
		System.out.println("This is sms sender...");
	}
}

public class MailSender implements Sender{

	@Override
	public void send() {
		// TODO Auto-generated method stub
		System.out.println("This is mail sender...");
	}
}
public class SendMailFactory implements Provider{
	
	@Override
	public Sender produce() {
		// TODO Auto-generated method stub
		return new MailSender();
	}
}
public class SendSmsFactory implements Provider {

	@Override
	public Sender produce() {
		// TODO Auto-generated method stub
		return new SmsSender();
	}
}
public class FactoryPattern {
	public static void main(String[] args) {
		//调用provide接口的实现方法得到一个SendMailFactory对象
		Provider provider=new SendMailFactory();
		//调用SendMailFactory里面的方法获取到MailSender对象
		Sender sender=provider.produce();
		sender.send();
	}
}

建造者模式(工厂模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来管理,用来创建复合对象,所谓复合对象就是指某个类中有不同的属性):

//抽象接口
public abstract class Builder {

	//第一步:装CPU
	public abstract void buildCPU();
	//第二部:装主板
	public abstract void buildMainBoard();
	//第三部:装硬盘
	public abstract void buildHD();
	//获得组装好的电脑
	public abstract Computer getComputer();
}

/*
 * 实现Builder接口已构造和装配改产品的各个部件
 * */

//具体装机人员
public class ConcreateBuilder extends Builder{

	Computer computer=new Computer();
	
	
	@Override
	public void buildCPU() {
		// TODO Auto-generated method stub
		computer.add("装CPU");
	}

	@Override
	public void buildMainBoard() {
		// TODO Auto-generated method stub
		computer.add("装主板");
	}

	@Override
	public void buildHD() {
		// TODO Auto-generated method stub
		computer.add("装硬盘");
	}

	@Override
	public Computer getComputer() {
		// TODO Auto-generated method stub
		return computer;
	}

	
}

//构造复杂对象。ConcreateBuilder创建该产品的内部表示并定义他的装配过程
public class Computer {
	//电脑组件组合
	private List<String> parts=new ArrayList<>();
	public void add(String part) {
		parts.add(part);
	}
	public void print() {
		for(int i=0;i<parts.size();i++) {
			System.out.println("组件"+parts.get(i)+"装好了");
		}
		System.out.println("电脑组装完毕……");
	}
}
//构造一个使用builder接口的对象

//装机人员装机
public class Director {
	public void Construct(Builder builder) {
		builder.buildCPU();
		builder.buildMainBoard();
		builder.buildHD();
	}
}
public class BuilderPattern {
	public static void main(String[] args) {
		Director director=new Director();
		Builder builder=new ConcreateBuilder();
		director.Construct(builder);
		Computer computer=builder.getComputer();
		computer.print();
	}
}
    1. 适配器设计模式(适配器模式是将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配所造成的了的兼容性问题。主要分为:类的适配器模式,对象的适配器模式,接口的适配器模式):
类的适配器模式:
public class Source {
	public void method1() {
		System.out.println("this is original method---");
	}
}
public interface Targetable {
	/*
	 * 与原类中的方法相同
	 * */
	public void method1();
	/*
	 * 新类的方法
	 * */
	public void method2();
}
public class Adapter extends Source implements Targetable{
	
	@Override
	public void method2() {
		// TODO Auto-generated method stub
		System.out.println("this is the targetable method---");
	}
	

}
public class AdaptPattern {
	public static void main(String[] args) {
		Targetable targetable=new Adapter();
		targetable.method1();
		targetable.method2();
	}
}

对象的适配器模式(基本思路和类的适配器模式相同,只是将Adapter类作修改,这次不继承Source类,而是持有Source类的实例,已达到解决兼容性问题):
public class Source {
	public void method1() {
		System.out.println("this is original method---");
	}
}
public interface Targetable {
	/*
	 * 与原类中的方法相同
	 * */
	public void method1();
	/*
	 * 新类的方法
	 * */
	public void method2();
}
public class Wrapper implements Targetable{
	private Source source;
	public Wrapper(Source source) {
	
		this.source=source;
	}
	@Override
	public void method1() {
		// TODO Auto-generated method stub
		source.method1();
	}
	@Override
	public void method2() {
		// TODO Auto-generated method stub
		System.out.println("this is the targetable method---");
	}
}
public class AdaptPattern {
	public static void main(String[] args) {
		Source source=new Source();
		
		Targetable targetable=new Wrapper(source);
		targetable.method1();
		targetable.method2();
	}
}

接口的适配器模式(有时候我们一个接口中有很多抽象方法,当我们去写改接口的实现类时,必须实现该接口中的所有方法,这明显有时比较浪费,因为不是每个方法都是我们需要的,有时只需要某一些,因此我们引用接口的适配器模式,借助一个抽象类,该抽象类实现了该接口,实现了所有方法,而我们不和原始的接口打交道,只和该抽象类取得联系,所以我们要写一个类,继承该抽象类,重写我们需要的方法就行):
理解:通过一个抽象类实现一个接口,重写里面的所有的方法,如果我们需要使用其中的某些方法,需要另外建立另一个类继承这个抽象方法,然后重写你需要的那个方法
//定义端口,提供通信服务

public interface Port {
	//远程SSH端口为22
	void SSH();
	//网络端口为80
	void NET();
	//Tomcat容器端口为8080
	void Tomcat();
	//mysql数据库端口为3306
	void MySQL();
}

//定义抽象类实现端口接口,但是什么事情都不做
public abstract class Wrapper implements Port{
	@Override
	public void SSH() {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void NET() {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void Tomcat() {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void MySQL() {
		// TODO Auto-generated method stub
		
	}
}

//提供聊天服务
//需要网络功能
public class Chat extends Wrapper{
	
	@Override
	public void NET() {
		// TODO Auto-generated method stub
		System.out.println("hello world");
	}
}
//网站服务器
//需要tomcat服务器,Mysql数据库,网络服务,远程服务
public class Server extends Wrapper{
	@Override
	public void SSH() {
		// TODO Auto-generated method stub
		System.out.println("Connect success---");
	}
	@Override
	public void NET() {
		System.out.println("WWW---");
	}
	@Override
	public void Tomcat() {
		// TODO Auto-generated method stub
		System.out.println("Tomcat is running---");
	}
	
	@Override
	public void MySQL() {
		// TODO Auto-generated method stub
		System.out.println("Mysql is running---");
	}
}
    1. 装饰者模式(顾名思义,装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰者对象和被装饰者对象实现同一个接口,装饰者对象持有被装饰对象的实例):
  1. public interface Shape {
    	void draw();
    }
    public class Rectangle implements Shape {
    
    	@Override
    	public void draw() {
    		// TODO Auto-generated method stub
    		System.out.println("Shape: Rectangle");
    	}
    }
    public class Circle implements Shape{
    
    	@Override
    	public void draw() {
    		// TODO Auto-generated method stub
    		System.out.println("Shape: Circle...");
    	}
    }
    //创建实现了Shape接口的抽象装饰类
    public abstract class ShapeDecorator implements Shape{
    	protected Shape decoratedShape;
    	public ShapeDecorator(Shape decoratedShape) {
    		this.decoratedShape=decoratedShape;
    	}
    	@Override
    	public void draw() {
    		// TODO Auto-generated method stub
    		decoratedShape.draw();
    	}
    }
    //创建扩展自ShapeDecorator类的实体装饰类
    public class RedShapeDecorator extends ShapeDecorator{
    
    	public  RedShapeDecorator(Shape decoratedShape) {
    		// TODO Auto-generated constructor stub
    		super(decoratedShape);
    	}
    	@Override
    	public void draw() {
    		// TODO Auto-generated method stub
    		decoratedShape.draw();
    		setRedBorder(decoratedShape);
    	}
    	private void setRedBorder(Shape decoratedShape) {
    		System.out.println("Border Color: Red");
    	}
    }
    public class DecoratorPattern {
    	public static void main(String[] args) {
    		Shape circle=new Circle();
    		Shape redCircle=new RedShapeDecorator(new Circle());
    		Shape redRectangle=new RedShapeDecorator(new Rectangle());
    		System.out.println("Circle with normal border");
            circle.draw();
    
            System.out.println("\nCircle of red border");
            redCircle.draw();
    
            System.out.println("\nRectangle of red border");
            redRectangle.draw();
    
    	}
    }
    

     

    1. 策略模式(策略模式定义了一系列算法,并将每个算法包装起来,使他们可以互相替换,且算法的变化不会影响到使用算法的客户。需要设计一个接口,为一系列实现类提供统一的方法,多个实现类实现改接口,设计一个抽象类(可有可无)属于辅助类。策略模式的决定权在于用户,系统本身提供不同算法的实现,新增或者删除算法,对各种算法做封装。因此策略模式多用于在算法决策系统中,外部用户只需要决定用哪个算法就可以):
  2. public class ConcreteStrategyA extends Stategy{
    
    	//算法A的实现方法
    	@Override
    	public void AlgorithmInterface() {
    		// TODO Auto-generated method stub
    		System.out.println("算法A的实现");
    	}
    }
    public class ConcreteStrategyB extends Stategy{
    
    	@Override
    	public void AlgorithmInterface() {
    		// TODO Auto-generated method stub
    	System.out.println("算法B的实现");	
    	}
    }
    public class ConcreteStrategyC extends Stategy{
    
    	@Override
    	public void AlgorithmInterface() {
    		// TODO Auto-generated method stub
    		System.out.println("算法C的实现");
    	}
    }
    //抽象算法的策略类,定义所有支持的算法的公共接口
    public abstract class Stategy {
    	//算法方法
    	public abstract void AlgorithmInterface();
    }
    public class Context {
    
    	Stategy stategy;
    	public Context(Stategy stategy) {
    		this.stategy=stategy;
    	}
    	public void contextInterface() {
    		stategy.AlgorithmInterface();
    	}
    }
    public class StrategyPattern {
    	public static void main(String[] args) {
    		Context context;
    		
    		context=new Context(new ConcreteStrategyA());
    		context.contextInterface();
    		
    		context=new Context(new ConcreteStrategyB());
    		context.contextInterface();
    		
    		context=new Context(new ConcreteStrategyC());
    		context.contextInterface();
    	}
    }

     

    1. 代理模式(代理模式指给对象提供一个代理对象,并由代理对象控制对原对象的引用。代理可以分为动态代理和静态代理。通过代理模式,可以利用代理对象为被代理对象添加额外的功能,以此来拓展被代理对象的功能。可以用于计算某个方法执行的时间,在执行方法前后记录日志等操作):
①静态代理(静态代理需要我们写出代理类和被代理类,而且一个代理类和被代理类一一对应。代理类和被代理类需要实现同一个接口,通过聚合使得代理对象中有被代理对象的引用,以此实现代理对象控制被代理对象的目的)
//共同实现的接口
public interface IService {
	void service();
}
//被代理类
public class Service implements IService{

	@Override
	public void service() {
		// TODO Auto-generated method stub
		System.out.println("被代理对象执行相关操作");
	}
}
//代理类
public class ProxyService implements IService{

	//持有被代理对象的引用
	private IService service;
	
	//默认代理Service类
	public ProxyService() {
		this.service=new Service();
	}
	//也可以代理实现相同接口的其他类
	public ProxyService(IService service) {
        this.service = service;
    }
	@Override
	public void service() {
		// TODO Auto-generated method stub
		System.out.println("开始执行service()方法");
        service.service();
        System.out.println("service()方法执行完毕");
	}
	
}
//测试了
public class ProxyPattern {

	public static void main(String[] args) {
		IService service=new Service();
		//传入被代理的对象
		ProxyService proxyService=new ProxyService(service);
		proxyService.service();
	}
}
1)


②动态代理(jdk1.3之后,java通过java,lang,reflect包中的三个类Proxy,InvocationHandler,Method来支持动态代理。动态代理常用于有若干个代理对象,且为每个被代理对象添加的功能是相同的(例如在每个方法运行前后记录日志)。)
1)动态代理的代理类不需要我们自己编写,由java自动产生代理类源代码并进行编译最后生成代理对象。
2)创建动态代理的步骤:
a.指明一系列的接口来创建一个代理对象
b.创建一个调用处理器(InvocationHandler)对象
c.将这个代理指定为某个其他对象的代理对象
d.在调用处理器的invoke()方法获取代理,一方面将调用传递给真实对象,另一方执行各种需要的操作。
public interface IService {
	void service();
}
//被代理类
public class Service implements IService{

	@Override
	public void service() {
		// TODO Auto-generated method stub
		System.out.println("被代理对象执行相关操作");
	}
}
public class ServiceInvocationHandler implements InvocationHandler{

	//被代理的对象
	private Object srcObject;
	public ServiceInvocationHandler(Object srcObject) {
		this.srcObject=srcObject;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("开始执行"+method.getName()+"方法");
		//执行原对象的相关操作
		Object returnObj=method.invoke(srcObject, args);
		System.out.println(method.getName()+"方法执行完毕");
		return returnObj;
	}
}
public class ProxyPattern {
	public static void main(String[] args) {
		IService service=new Service();
		Class<? extends IService> clazz=service.getClass();
		IService proxyService=(IService) Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new ServiceInvocationHandler(service));
		proxyService.service();
	}
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值