常用设计模式

一、单例模式:

1、只能有一个实例;2、单例类必须自己创建自己的实例;3、单例必须给所有对象提供这一实例。

1)、懒汉式(延迟加载,用到时才加载):

  优点:延迟加载(需要的时候才去加载),适合单线程操作
  缺点: 线程不安全,在多线程中很容易出现不同步的情况,如在数据库对象进行的频繁读写操作时。
 1 /**
 2  * 懒汉式
 3  * 
 4  *     优点:延迟加载(需要的时候才去加载),适合单线程操作
 5     缺点: 线程不安全,在多线程中很容易出现不同步的情况,如在数据库对象进行的频繁读写操作时。
 6  * 
 7  * @author admin
 8  *
 9  */
10 public class Singleton {
11 
12     private static Singleton obj = null;
13 
14     // 私有构造方法,防止被实例化
15     private Singleton() {
16     }
17 
18     
19     public static Singleton getSingleton() {
20         if (obj == null) {
21             obj = new Singleton();
22         }
23         return obj;
24     }
25 }

2)、饿汉式(立即加载,自行new,向外提供):

  优点:线程安全

 1 /**
 2  * 饿汉式单例模式
 3  * 1、构造器私有
 4  * 2、自行创建
 5  * 3、向外提供这个实例
 6  * 4、强调这是一个单例用关键字final
 7  * 
 8  * 
 9  * @author admin
10  *
11  */
12 public class Singleton2 {
13 
14     private static Singleton2 instance = new Singleton2();
15     private Singleton2(){}
16 }

 

二、工厂模式

1、简单工厂模式:简单工厂模式是属于创建型模式,又叫做静态工厂方法,不属于23种GOF设计模式之一。可以理解为是不同工厂模式的一个特殊实现。

例如:抽象一个面条基类,(接口也可以),这是产品的抽象类。

1 public abstract class INoodles {
2     /**
3      * 描述每种面条啥样的
4      */
5     public abstract void desc();
6 }

先来一份兰州拉面(具体的产品类):

1 public class LzNoodles extends INoodles {
2     @Override
3     public void desc() {
4         System.out.println("兰州拉面 上海的好贵 家里才5 6块钱一碗");
5     }
6 }

程序员加班必备也要吃泡面(具体的产品类):

1 public class PaoNoodles extends INoodles {
2     @Override
3     public void desc() {
4         System.out.println("泡面好吃 可不要贪杯");
5     }
6 }

还有我最爱吃的家乡的干扣面(具体的产品类):

1 public class GankouNoodles extends INoodles {
2     @Override
3     public void desc() {
4         System.out.println("还是家里的干扣面好吃 6块一碗");
5     }
6 }

准备工作做完了,我们来到一家“简单面馆”(简单工厂类),菜单如下:

 1 public class SimpleNoodlesFactory {
 2     public static final int TYPE_LZ = 1;//兰州拉面
 3     public static final int TYPE_PM = 2;//泡面
 4     public static final int TYPE_GK = 3;//干扣面
 5 
 6     public static INoodles createNoodles(int type) {
 7         switch (type) {
 8             case TYPE_LZ:
 9                 return new LzNoodles();
10             case TYPE_PM:
11                 return new PaoNoodles();
12             case TYPE_GK:
13             default:
14                 return new GankouNoodles();
15         }
16     }
17 }

简单面馆就提供三种面条(产品),你说你要啥,他就给你啥。这里我点了一份干扣面:

1 /**
2  * 简单工厂模式
3  */
4  INoodles noodles = SimpleNoodlesFactory.createNoodles(SimpleNoodlesFactory.TYPE_GK);
5  noodles.desc();

2、工厂方法模式:

在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做。该核心类成为一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。

工厂:

 1 package com.demoFound.factoryMethod.factory;  
 2   
 3 import com.demoFound.factoryMethod.message.IMyMessage;  
 4   
 5 /** 
 6  * 工厂方法模式_工厂接口 
 7  *  
 8  * @author popkidorc 
 9  *  
10  */  
11 public interface IMyMessageFactory {  
12   
13     public IMyMessage createMessage(String messageType);  
14 }
 1 package com.demoFound.factoryMethod.factory;  
 2   
 3 import java.util.HashMap;  
 4 import java.util.Map;  
 5   
 6 import com.demoFound.factoryMethod.message.IMyMessage;  
 7 import com.demoFound.factoryMethod.message.MyMessageEmail;  
 8 import com.demoFound.factoryMethod.message.MyMessageOaTodo;  
 9 import com.demoFound.factoryMethod.message.MyMessageSms;  
10   
11 /** 
12  * 工厂方法模式_工厂实现 
13  *  
14  * @author popkidorc 
15  *  
16  */  
17 public class MyMessageFactory implements IMyMessageFactory {  
18   
19     @Override  
20     public IMyMessage createMessage(String messageType) {  
21         // 这里的方式是:消费者知道自己想要什么产品;若生产何种产品完全由工厂决定,则这里不应该传入控制生产的参数。  
22         IMyMessage myMessage;  
23         Map<String, Object> messageParam = new HashMap<String, Object>();  
24         // 根据某些条件去选择究竟创建哪一个具体的实现对象,条件可以传入的,也可以从其它途径获取。  
25         // sms  
26         if ("SMS".equals(messageType)) {  
27             myMessage = new MyMessageSms();  
28             messageParam.put("PHONENUM", "123456789");  
29         } else  
30         // OA待办  
31         if ("OA".equals(messageType)) {  
32             myMessage = new MyMessageOaTodo();  
33             messageParam.put("OAUSERNAME", "testUser");  
34         } else  
35         // email  
36         if ("EMAIL".equals(messageType)) {  
37             myMessage = new MyMessageEmail();  
38             messageParam.put("EMAIL", "test@test.com");  
39         } else  
40         // 默认生产email这个产品  
41         {  
42             myMessage = new MyMessageEmail();  
43             messageParam.put("EMAIL", "test@test.com");  
44         }  
45         myMessage.setMessageParam(messageParam);  
46         return myMessage;  
47     }  
48 }

产品:

 1 package com.demoFound.factoryMethod.message;  
 2   
 3 import java.util.Map;  
 4   
 5 /** 
 6  * 工厂方法模式_产品接口 
 7  *  
 8  * @author popkidorc 
 9  *  
10  */  
11 public interface IMyMessage {  
12   
13     public Map<String, Object> getMessageParam();  
14   
15     public void setMessageParam(Map<String, Object> messageParam);  
16   
17     public void sendMesage() throws Exception;// 发送通知/消息  
18   
19 }  
 1 package com.demoFound.factoryMethod.message;  
 2   
 3 import java.util.Map;  
 4   
 5 /** 
 6  * 工厂方法模式_虚拟产品类 
 7  *  
 8  * @author popkidorc 
 9  *  
10  */  
11 public abstract class MyAbstractMessage implements IMyMessage {  
12   
13     private Map<String, Object> messageParam;// 这里可以理解为生产产品所需要的原材料库。最好是个自定义的对象,这里为了不引起误解使用Map。  
14   
15     @Override  
16     public Map<String, Object> getMessageParam() {  
17         return messageParam;  
18     }  
19   
20     @Override  
21     public void setMessageParam(Map<String, Object> messageParam) {  
22         this.messageParam = messageParam;  
23     }  
24 }  
 1 package com.demoFound.factoryMethod.message;  
 2   
 3 /** 
 4  * 工厂方法模式_oa待办产品 
 5  *  
 6  * @author popkidorc 
 7  *  
 8  */  
 9 public class MyMessageOaTodo extends MyAbstractMessage {  
10   
11     @Override  
12     public void sendMesage() throws Exception {  
13         // TODO Auto-generated method stub  
14         if (null == getMessageParam()  
15                 || null == getMessageParam().get("OAUSERNAME")  
16                 || "".equals(getMessageParam().get("OAUSERNAME"))) {  
17             throw new Exception("发送OA待办,需要传入OAUSERNAME参数");// 为了简单起见异常也不自定义了  
18         }// 这里的参数需求就比较多了不一一处理了  
19   
20         System.out  
21                 .println("我是OA待办,发送通知给" + getMessageParam().get("OAUSERNAME"));  
22     }  
23   
24 }  
 1 package com.demoFound.factoryMethod.message;  
 2   
 3 /** 
 4  * 工厂方法模式_sms产品 
 5  *  
 6  * @author popkidorc 
 7  *  
 8  */  
 9 public class MyMessageSms extends MyAbstractMessage {  
10   
11     @Override  
12     public void sendMesage() throws Exception {  
13         // TODO Auto-generated method stub  
14         if (null == getMessageParam()  
15                 || null == getMessageParam().get("PHONENUM")  
16                 || "".equals(getMessageParam().get("PHONENUM"))) {  
17             throw new Exception("发送短信,需要传入PHONENUM参数");// 为了简单起见异常也不自定义了  
18         }// 另外短信信息,以及其他各种协议参数等等都要处理  
19   
20         System.out.println("我是短信,发送通知给" + getMessageParam().get("PHONENUM"));  
21     }  
22   
23 }

消费者:

 1 package com.demoFound.factoryMethod;  
 2   
 3 import com.demoFound.factoryMethod.factory.IMyMessageFactory;  
 4 import com.demoFound.factoryMethod.factory.MyMessageFactory;  
 5 import com.demoFound.factoryMethod.message.IMyMessage;  
 6   
 7 /** 
 8  * 工厂方法模式_消费者类 
 9  *  
10  * @author popkidorc 
11  *  
12  */  
13 public class MyFactoryMethodMain {  
14   
15     public static void main(String[] args) {  
16         IMyMessageFactory myMessageFactory = new MyMessageFactory();  
17         IMyMessage myMessage;  
18         // 对于这个消费者来说,不用知道如何生产message这个产品,耦合度降低  
19         try {  
20             // 先来一个短信通知  
21             myMessage = myMessageFactory.createMessage("SMS");  
22             myMessage.sendMesage();  
23   
24             // 来一个oa待办  
25             myMessage = myMessageFactory.createMessage("OA");  
26             myMessage.sendMesage();  
27   
28             // 来一个邮件通知  
29             myMessage = myMessageFactory.createMessage("EMAIL");  
30             myMessage.sendMesage();  
31         } catch (Exception e) {  
32             e.printStackTrace();  
33         }  
34     }  
35 }

3、抽象工厂模式

定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。

抽象工厂模式与工厂方法模式的区别:抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象

例如:
 1 interface IProduct1 {  
 2     public void show();  
 3 }  
 4 interface IProduct2 {  
 5     public void show();  
 6 }  
 7   
 8 class Product1 implements IProduct1 {  
 9     public void show() {  
10         System.out.println("这是1型产品");  
11     }  
12 }  
13 class Product2 implements IProduct2 {  
14     public void show() {  
15         System.out.println("这是2型产品");  
16     }  
17 }  
18   
19 interface IFactory {  
20     public IProduct1 createProduct1();  
21     public IProduct2 createProduct2();  
22 }  
23 class Factory implements IFactory{  
24     public IProduct1 createProduct1() {  
25         return new Product1();  
26     }  
27     public IProduct2 createProduct2() {  
28         return new Product2();  
29     }  
30 }  
31   
32 public class Client {  
33     public static void main(String[] args){  
34         IFactory factory = new Factory();  
35         factory.createProduct1().show();  
36         factory.createProduct2().show();  
37     }  
38 }

又如;

1     package ppp;  
2       
3     //Person接口定义  
4     public interface Person {  
5         public String sayHello(String name);  
6         public String sayGoodbye(String name);  
7     }  
 1     package ppp;  
 2     //American类实现Person接口  
 3     public class American implements Person {  
 4         public String sayHello(String name){  
 5             return name+",hello";  
 6         }  
 7         public String sayGoodbye(String name)  
 8         {  
 9             return name+",goodbye";  
10         }  
11     }  

 

 1     package ppp;    
 2     //Chinese类实现Person接口  
 3     public class Chinese implements Person {  
 4         public String sayHello(String name){  
 5             return name+",您好";  
 6         }  
 7         public String sayGoodbye(String name)  
 8         {  
 9             return name+",下次再见";  
10         }  
11     }  

 

 1     package ppp;  
 2       
 3     public class PersonFactory {  
 4         public Person getPerson(String ethnic)  
 5         {  
 6             if(ethnic.equalsIgnoreCase("chin"))  
 7             {  
 8                 return new Chinese();  
 9             }else{  
10                 return new American();        
11             }  
12         }  
13     }  

 

 1     package ppp;  
 2       
 3     public class FactoryTest {  
 4         public static void main(String[] args){  
 5             //创建PersonFactory实例 ,获得工厂实例   
 6             PersonFactory pf = new PersonFactory();  
 7             //定义接口Person实例,面向接口编程   
 8             Person p = null;  
 9             //使用工厂获得person实例  
10             p = pf.getPerson("chin");  
11             //下面调用Person接口方法  
12             System.out.println(p.sayHello("wawa"));  
13             System.out.println(p.sayGoodbye("wawa"));  
14             //使用工厂获得Person的另一个实例  
15             p = pf.getPerson("ame");  
16             //再次调用Person接口的方法  
17             System.out.println(p.sayHello("wawa"));  
18             System.out.println(p.sayGoodbye("wawa"));  
19         }  
20     }  

 

sping中的单例和工厂模式:

spring就是一个最大的工厂,例如,Spring使用配置文件管理所有的Bean,其配置文件中的Bean由Spring工厂负责生成和管理,既使没有bean的工厂类,程序依然可以使用工厂模式,因为Sping就是工厂。

 

 

 

 

 

 

 

 

 

 
 
 
posted @ 2018-12-02 16:33  乌瑟尔  阅读(239)  评论(0编辑  收藏  举报