常用的几种设计模式
来源:互联网 发布:网络语言暴力视频 编辑:程序博客网 时间:2024/05/22 01:33
1.单例设计模式singleton——只能产生一个实例化对象的设计模式
(为什么不用静态变量代替呢?因为静态变量在程序一开始就创建了对象,可能会比较消耗资源)
public class Singleton { private static Singleton uniqueInstance; private Singleton(){} public static Singleton getInstance(){ if(uniqueInstance == null){ uniqueInstance = new Singleton(); } return uniqueInstance; }}public class singletonTest { public static void main(String args[]){ Singleton s1 = Singleton.getInstance(); Singleton s2 = Singleton.getInstance(); System.out.println("s1:" + s1 + ",s2:" + s2); }}
运行结果显示:
s1:designPattern.Singleton@6f94fa3e,s2:designPattern.Singleton@6f94fa3e
两个对象的地址相同,表示只产生了一个实例化对象
2.工厂设计模式Factory—将对象的创建封装起来
(1)简单工厂:程序中只有一个工厂,在工厂内部根据数据逻辑判断来创建不同对象
实例:假设有一个Sender接口,以及实现了这两个接口的类:MailSender和SmsSender
public interface Sender{ public void Send();}public class MailSender implements Sender{ public void Send(){ System.out.println("mailsender!"); }}public class SmsSender implements Sender{ public void Send(){ System.out.println("smssender!"); }}现在设计一个简单工厂对象用于产生这两个类的实例化对象如下:
public class SendFactory{ public Sender produce(String type){ if("mail".equals(type)){ return new MailSender(); }else if("sms".equals(type)){ return new SmsSender(); }else{ return null; } }}调用过程:
SendFactory sendproduct = new SendFactory();Sender send = sendproduct.produce("mail");整个代码中只有一个工厂类,这就是简单工厂。
(2)工厂方法:针对于简单工厂的改进(由于传送数据出错导致返回null),对于每一种类设置一个工厂方法用于返回相应的对象。
工厂方法代码如下:
public class SendfunctionFactory{ public Sender produceMail(){ return new MailSender(); } public Sender produceSms(){ return new SmsSender(); }}调用过程:
SendfunctionFactory factory = new SendfunctionFactory();Sender send = factory.produceMail();大部分情况下,都会对上述方法进行改进,即将上述工厂方法设置为静态的,这样,不实例化工厂对象也可以调用相应的工厂方法。
(3)抽象工厂:针对于工厂方法中的不足—当添加了一个子类时,需要在已有的工厂中添加一个方法,改变了已有的代码。改进:写一个工厂接口,每一个类都有一个相应的工厂实现该接口,当添加一个类的时候,只需要添加一个工厂类就行,不必修改已有的工厂类。
代码如下:
public interface provider{ public Sender produce();}public class SendMailFactory implements provider{ public Sender produce(){ return new MailSender(); }}public class SendSmsFactory implements provider{ public Sender produce(){ return new SmsSender(); }}调用方式如下:
provider pro = new SendMailFactory();Sender sender = pro.produce();调用时指明是哪个工厂。
3.适配器设计模式adapter—将一个种类型转换成另外一种适合场景的类型
(1)类的适配器模式:希望将一个类转换成满足另一个接口的新类。
创建一个新类,继承原有的类,实现新的接口
实例:假设有一个源类Source和一个目标接口Targetable
public class Source{ public void method1(){ System.out.println("source's method1"); }}public interface Targetable{ public void method1(); public void method2();}现在想要通过适配器使source类可以实现目标接口,方式是,编写一个新类:
public class Adaptor extends Source implements Targetable{ public void method2(){ System.out.println("Adaptor's method2"); }}调用的方式:
Targetable target = new Adaptor(); target.method1(); target.method2();
(2)对象的适配器模式:希望将一个对象转换成一个新接口的对象
实现方式是,创建一个新类,该类包含一个原对象的属性,并且该类实现了接口中的方法。
public class Newclass implements Targetable{ private Source source; public Newclass(Source source){ super(); this.source = source; } public void method1(){ System.out.println("newclass's method1"); } public void method2(){ System.out.println("newclass's method2"); }}使用方式,使用给定的对象构造适配器类:
Source source = new Source(); Targetable target = new Newclass(source); target.method1(); target.method2();
比如有一个接口有两个方法:
public interface Sourceable{ public void method1(); public void method2();}现在想产生两个类,类1只想要方法1,类2只想要方法2,实现方式是先构建一个抽象类:
public abstract class newclass implements Sourceable{ public void method1(){} public void method2(){}}然后再让两个类继承该抽象类:
public class SourceSub1 extends newclass{ public void method1(){ System.out.println("sourcesub1's method1"); }}public class SourceSub2 extends newclass{ public void method2(){ System.out.println("sourcesub2's method2"); }}由于继承时可以不必重写所有方法,所以两个子类只需要重写自己想用的方法即可,使用方式:
Sourceable source1 = new SourceSub1(); Sourceable source2 = new SourceSub2(); source1.method1(); source1.method2(); source2.method1(); source2.method2();
4.装饰设计模式—给类添加新的功能
(为什么不用继承?因为继承时静态的,装饰设计模式可以动态的添加功能,避免了继承体系的臃肿)
对于一个类和一个接口,编写一个装饰类实现该接口,装饰类中含有源类的实例化对象。
如下,假设有一个接口SourceAble,和一个实现了该接口的类SourceClass:
public interface SourceAble{ public void method();}public class SourceClass implements SourceAble{ public void method(){ System.out.println("source method"); }}现在想丰富该类中method方法的功能,实现方式是编写一个装饰类:
public class DecoratorClass implements SourceAble{ private SourceAble source; public DecoratorClass(SourceAble source){ super(); this.source = source; } public void method(){ System.out.println("before decorator"); source.method(); System.out.println("after decorator"); }}使用方式:
SourceAble source = new SourceClass(); SourceAble dec = new DecoratorClass(source); dec.method();
(5)代理设计模式proxy—设计一个对象,该对象为另一个对象提供替身以控制该对象的访问,处理代理对象就像处理原始对象一样。(被代理的对象可以是远程对象、创建开销大的对象或者需要安全控制的对象)
代理模式和装饰模式的区别:
代理模式注重控制,原始的功能不变;
装饰模式注重功能的添加;
(个人觉得,在代码结构上没什么区别,主要区别是你这段代码的目的性)
动态代理模式— 一个代理类可以代理所有需要被代理接口(功能相似的接口)的子类对象
①JDK动态代理:代理的类实现了某一接口
用到了InvocationHandler接口
public interface InvocationHandler { public Object invoke(Object proxy,Method method,Object[] args) throws Throwable; }说明:
Object proxy:指被代理的对象。
Method method:要调用的方法
Object[] args:方法调用时所需要的参数
用到了Proxy类:
Proxy类是专门完成代理的操作类,可以通过此类为一个或多个接口动态地生成实现类,此类提供了如下的操作方法:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
参数说明:
ClassLoader loader:类加载器
Class<?>[] interfaces:得到全部的接口
InvocationHandler h:得到InvocationHandler接口的子类实例
实例代码如下:
interface BookFacade{ public void addBook();}class BookFacadeImpl implements BookFacade{ public void addBook(){ System.out.println("add book"); }}class BookFacadeProxy implements InvocationHandler{//代理类实现InvocationHandler接口 private Object target; public Object bind(Object target){//执行对象的绑定 this.target = target; return Proxy.newProxyInstance(target.getClass().getClassLoader() ,target.getClass().getInterfaces(),this); } public Object invoke(Object proxy, Method method, Object[] args)throws Throwable{//实现接口里面的invoke方法 Object result = null; System.out.println("begin"); result = method.invoke(target,args); System.out.println("end"); return result; }}public class JDKProxy { public static void main(String args[]){ BookFacadeProxy proxy = new BookFacadeProxy(); BookFacade bookProxy = (BookFacade)proxy.bind(new BookFacadeImpl()); bookProxy.addBook(); }}
②CGLIB动态代理:代理的类没有实现接口
public class BookFacadeCglib implements MethodInterceptor { private Object target; public Object getInstance(Object target) { this.target = target; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.target.getClass()); // 回调方法 enhancer.setCallback(this); // 创建代理对象 return enhancer.create(); } public Object intercept(Object obj, Method method, Object[] args,MethodProxy proxy) throws Throwable { System.out.println("事物开始"); proxy.invokeSuper(obj, args); System.out.println("事物结束"); return null; } }
(6)观察者模式observer—当一个对象变化的时候,跟其相关联的对象中的相应值也会变化
需要有两个接口:Subjec(被观察的对象接口),Observer(观察者的接口):
public interface Observer{ public void update();}public interface Subject{ public void add(Observer observer);//用于增加观察者 public void del(Observer observer);//用于删除观察者 public void notifyObservers();//用于通知所有观察者 public void operation();}
定义一个抽象类实现被观察者接口:
public abstract class AbstractSubject implements Subject{ private List<myObserver> list = new ArrayList<myObserver>(); public void add(myObserver observer){ list.add(observer); } public void del(myObserver observer){ list.remove(observer); } public void notifyObservers(){ for(myObserver observer : list){ observer.update(); } }}
定义两个观察者类以及一个被观察者类:
public class Observer1 implements myObserver{ public void update(){ System.out.println("Observer1's update"); }}public class Observer2 implements myObserver{ public void update(){ System.out.println("Observer2's update"); }}public class mySubject extends AbstractSubject{ public void operation(){ System.out.println("my operation"); notifyObservers(); }}使用方法:
Subject sub = new mySubject(); sub.add(new Observer1()); sub.add(new Observer2()); sub.operation();
- 几种常用的设计模式
- 几种常用的设计模式介绍
- 几种常用的设计模式介绍
- 几种常用的设计模式介绍
- 几种常用的设计模式
- 面试-几种常用的设计模式
- 常用的几种设计模式
- 几种常用的设计模式
- 几种常用的设计模式
- 几种常用的Java设计模式
- 几种常用的设计模式介绍
- 几种常用的设计模式
- 几种常用的ios设计模式
- iOS常用的几种设计模式
- 几种常用的设计模式介绍
- 几种常用的设计模式介绍
- 几种常用的设计模式介绍
- 几种常用的设计模式介绍
- Win7专业版 下安装ArcGIS desktop 9.3总结
- API接口对当今的小程序、APP、移动端的重要性
- 获取安卓手机唯一设备号
- spring boot mybatis+分页配置
- ToolBar回退键的调用和设置颜色
- 常用的几种设计模式
- Linux每次开机都要source profile的解决办法
- 开始Blog之旅
- springboot+quartz分布式
- springmvc框架集成activemq使用序列的一个记录
- Hexo+Github搭建个人博客(一)——开始搭建
- Hexo+Github搭建个人博客(二)——配置&主题
- java编写购物管理系统2----JDBC连接数据库
- Hexo+Github搭建个人博客(三)——百度分享集成