1、工厂方法模式
1-1 普通工厂模式
举例如下:(我们举一个发送邮件和短信的例子)
首先,创建二者的共同接口:
1 public interface Sender { 2 public void Send(); 3 }
其次,创建实现类:
1 public class MailSender implements Sender { 2 @Override 3 public void Send() { 4 System.out.println("this is mailsender!"); 5 } 6 }
1 public class SmsSender implements Sender { 2 3 @Override 4 public void Send() { 5 System.out.println("this is sms sender!"); 6 } 7 }
最后,建工厂类:
1 public class SendFactory { 2 3 public Sender produce(String type) { 4 if ("mail".equals(type)) { 5 return new MailSender(); 6 } else if ("sms".equals(type)) { 7 return new SmsSender(); 8 } else { 9 System.out.println("请输入正确的类型!"); 10 return null; 11 } 12 } 13 }
我们来测试下:
public class FactoryTest { public static void main(String[] args) { SendFactory factory = new SendFactory(); Sender sender = factory.produce("sms"); sender.Send(); } }
输出:this is sms sender!
1-2 多个工厂方法模式
将上面的代码做下修改,改动下SendFactory类就行,如下:
1 public class SendFactory { 2 public Sender produceMail(){ 3 4 return new MailSender(); 5 } 6 7 public Sender produceSms(){ 8 return new SmsSender(); 9 } 10 }
测试类如下:
1 public class FactoryTest { 2 3 public static void main(String[] args) { 4 SendFactory factory = new SendFactory(); 5 Sender sender = factory.produceMail(); 6 sender.Send(); 7 } 8 }
输出:this is mailsender!
1-3、静态工厂方法模式
将上面的多个工厂方法模式里的方法置为静态的,不需要创建实例,直接调用即可。
1 public class SendFactory { 2 3 public static Sender produceMail(){ 4 return new MailSender(); 5 } 6 7 public static Sender produceSms(){ 8 return new SmsSender(); 9 } 10 }
1 public class FactoryTest { 2 3 public static void main(String[] args) { 4 Sender sender = SendFactory.produceMail(); 5 sender.Send(); 6 } 7 }
输出:this is mailsender!
2、抽象工厂模式
1 public interface Sender { 2 public void Send(); 3 }
两个实现类:
1 public class MailSender implements Sender { 2 @Override 3 public void Send() { 4 System.out.println("this is mailsender!"); 5 } 6 }
1 public class SmsSender implements Sender { 2 3 @Override 4 public void Send() { 5 System.out.println("this is sms sender!"); 6 } 7 }
两个工厂类:
1 public class SendMailFactory implements Provider { 2 3 @Override 4 public Sender produce(){ 5 return new MailSender(); 6 } 7 }
1 public class SendSmsFactory implements Provider{ 2 3 @Override 4 public Sender produce() { 5 return new SmsSender(); 6 } 7 }
在提供一个接口:
1 public interface Provider { 2 public Sender produce(); 3 }
测试类:
1 public class Test { 2 3 public static void main(String[] args) { 4 Provider provider = new SendMailFactory(); 5 Sender sender = provider.produce(); 6 sender.Send(); 7 } 8 }
Spring中工厂设计模式的使用
Spring使用工厂模式可以通过 BeanFactory
或 ApplicationContext
创建 bean 对象。
两者对比:
BeanFactory
:延迟注入(使用到某个 bean 的时候才会注入),相比于BeanFactory
来说会占用更少的内存,程序启动速度更快。ApplicationContext
:容器启动的时候,不管你用没用到,一次性创建所有 bean 。BeanFactory
仅提供了最基本的依赖注入支持,ApplicationContext
扩展了 BeanFactory
,除了有BeanFactory
的功能之外还有额外更多功能,所以一般开发人员使用ApplicationContext
会更多。ApplicationContext的三个实现类:
ClassPathXmlApplication
:把上下文文件当成类路径资源。FileSystemXmlApplication
:从文件系统中的 XML 文件载入上下文定义信息。XmlWebApplicationContext
:从Web系统中的XML文件载入上下文定义信息。Example:
1 import org.springframework.context.ApplicationContext; 2 import org.springframework.context.support.FileSystemXmlApplicationContext; 3 4 public class App { 5 public static void main(String[] args) { 6 ApplicationContext context = new FileSystemXmlApplicationContext( 7 "C:/work/IOC Containers/springframework.applicationcontext/src/main/resources/bean-factory-config.xml"); 8 9 HelloApplicationContext obj = (HelloApplicationContext) context.getBean("helloApplicationContext"); 10 obj.getMsg(); 11 } 12 }
3、单例模式
首先我们写一个简单的单例类:
1 public class Singleton { 2 3 /* 持有私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载 */ 4 private static Singleton instance = null; 5 6 /* 私有构造方法,防止被实例化 */ 7 private Singleton() { 8 } 9 10 /* 静态工程方法,创建实例 */ 11 public static Singleton getInstance() { 12 if (instance == null) { 13 instance = new Singleton(); 14 } 15 return instance; 16 } 17 18 }
这个类可以满足基本要求,但是,像这样毫无线程安全保护的类,如果我们把它放入多线程的环境下,肯定就会出现问题了,如何解决?我们首先会想到对getInstance方法加synchronized关键字,如下:
1 public static synchronized Singleton getInstance() { 2 if (instance == null) { 3 instance = new Singleton(); 4 } 5 return instance; 6 }
但是,synchronized关键字锁住的是这个对象,这样的用法,在性能上会有所下降,因为每次调用getInstance(),都要对对象上锁,事实上,只有在第一次创建对象的时候需要加锁,之后就不需要了,所以,这个地方需要改进。我们改成下面这个:
1 public static Singleton getInstance() { 2 if (instance == null) { 3 synchronized (instance) { 4 if (instance == null) { 5 instance = new Singleton(); 6 } 7 } 8 } 9 return instance; 10 }
1 public class Singleton { 2 3 /* 私有构造方法,防止被实例化 */ 4 private Singleton() { 5 } 6 7 /* 此处使用一个内部类来维护单例 */ 8 private static class SingletonFactory { 9 private static Singleton instance = new Singleton(); 10 } 11 12 /* 获取实例 */ 13 public static Singleton getInstance() { 14 return SingletonFactory.instance; 15 } 16 17 }
也有人这样实现:因为我们只需要在创建类的时候进行同步,所以只要将创建和getInstance()分开,单独为创建加synchronized关键字,也是可以的:
1 public class SingletonTest { 2 3 private static SingletonTest instance = null; 4 5 private SingletonTest() { 6 } 7 8 private static synchronized void syncInit() { 9 if (instance == null) { 10 instance = new SingletonTest(); 11 } 12 } 13 14 public static SingletonTest getInstance() { 15 if (instance == null) { 16 syncInit(); 17 } 18 return instance; 19 } 20 }
以上都是懒汉式单例,下面实现一个饿汉式的单例
1 public class SingletonTest { 2 3 private static final SingletonTest instance =new SingletonTest(); 4 5 private SingletonTest() { 6 } 7 8 public static SingletonTest getInstance() { 9 return instance; 10 } 11 }
Spring中单例设计模式的使用
Spring中bean的默认作用域就是singleton(单例)的,除了singleton作用域,Spring中bean还有下面几种作用域:
Spring实现单例的方式:
<bean id="userService" class="top.snailclimb.UserService" scope="singleton"/>
@Scope(value = "singleton")
Spring通过ConcurrentHashMap
实现单例注册表的特殊方式实现单例模式。Spring实现单例的核心代码如下:
1 // 通过 ConcurrentHashMap(线程安全) 实现单例注册表 2 private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64); 3 4 public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { 5 Assert.notNull(beanName, "‘beanName‘ must not be null"); 6 synchronized (this.singletonObjects) { 7 // 检查缓存中是否存在实例 8 Object singletonObject = this.singletonObjects.get(beanName); 9 if (singletonObject == null) { 10 //...省略了很多代码 11 try { 12 singletonObject = singletonFactory.getObject(); 13 } 14 //...省略了很多代码 15 // 如果实例对象在不存在,我们注册到单例注册表中。 16 addSingleton(beanName, singletonObject); 17 } 18 return (singletonObject != NULL_OBJECT ? singletonObject : null); 19 } 20 } 21 //将对象添加到单例注册表 22 protected void addSingleton(String beanName, Object singletonObject) { 23 synchronized (this.singletonObjects) { 24 this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT)); 25 26 } 27 } 28 }
4、建造者模式
(1) 产品角色:包含多个组成部件的复杂对象。
1 class Product{ 2 private String partA; 3 private String partB; 4 private String partC; 5 public void setPartA(String partA){ 6 this.partA=partA; 7 } 8 public void setPartB(String partB){ 9 this.partB=partB; 10 } 11 public void setPartC(String partC) { 12 this.partC=partC; 13 } 14 public void show(){ 15 //显示产品的特性 16 } 17 }
(2) 抽象建造者:包含创建产品各个子部件的抽象方法。
1 abstract class Builder 2 { 3 //创建产品对象 4 protected Product product=new Product(); 5 public abstract void buildPartA(); 6 public abstract void buildPartB(); 7 public abstract void buildPartC(); 8 //返回产品对象 9 public Product getResult() 10 { 11 return product; 12 } 13 }
(3) 具体建造者:实现了抽象建造者接口。
1 public class ConcreteBuilder extends Builder 2 { 3 public void buildPartA() 4 { 5 product.setPartA("建造 PartA"); 6 } 7 public void buildPartB() 8 { 9 product.setPartA("建造 PartB"); 10 } 11 public void buildPartC() 12 { 13 product.setPartA("建造 PartC"); 14 } 15 }
(4) 指挥者:调用建造者中的方法完成复杂对象的创建。
1 class Director 2 { 3 private Builder builder; 4 public Director(Builder builder) 5 { 6 this.builder=builder; 7 } 8 //产品构建与组装方法 9 public Product construct() 10 { 11 builder.buildPartA(); 12 builder.buildPartB(); 13 builder.buildPartC(); 14 return builder.getResult(); 15 } 16 }
(5) 客户类。
1 public class Client 2 { 3 public static void main(String[] args) 4 { 5 Builder builder=new ConcreteBuilder(); 6 Director director=new Director(builder); 7 Product product=director.construct(); 8 product.show(); 9 } 10 }
Spring中建造者模式的使用
spring框架,主要是用来管理对象,创建一个对象是极其复杂的,建造者模式在解析xml文件,创建BeanDefinition中发挥很大的作用。不想在这里做更细节的分析,但是可以找段代码,分析spring是如何使用它。
段落1:spring-security中解析xml
5、原型模式
1 public class Prototype implements Cloneable, Serializable { 2 3 private static final long serialVersionUID = 1L; 4 private String string; 5 6 private SerializableObject obj; 7 8 /* 浅复制 */ 9 public Object clone() throws CloneNotSupportedException { 10 Prototype proto = (Prototype) super.clone(); 11 return proto; 12 } 13 14 /* 深复制 */ 15 public Object deepClone() throws IOException, ClassNotFoundException { 16 17 /* 写入当前对象的二进制流 */ 18 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 19 ObjectOutputStream oos = new ObjectOutputStream(bos); 20 oos.writeObject(this); 21 22 /* 读出二进制流产生的新对象 */ 23 ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); 24 ObjectInputStream ois = new ObjectInputStream(bis); 25 return ois.readObject(); 26 } 27 28 public String getString() { 29 return string; 30 } 31 32 public void setString(String string) { 33 this.string = string; 34 } 35 36 public SerializableObject getObj() { 37 return obj; 38 } 39 40 public void setObj(SerializableObject obj) { 41 this.obj = obj; 42 } 43 44 } 45 46 class SerializableObject implements Serializable { 47 private static final long serialVersionUID = 1L; 48 }
Spring中原型模式的使用
结束。
原文:https://www.cnblogs.com/it-deepinmind/p/13223665.html