美文网首页
java常用设计模式

java常用设计模式

作者: 吕侯爷 | 来源:发表于2017-04-18 21:12 被阅读0次

    一、单例模式(有的书上说叫单态模式其实都一样)

    该模式主要目的是使内存中保持1个对象。看下面的例子:

    方法一
    public class Singleton{
       private static final Singleton instance = new Singleton();
       private Singleton(){}
    //通过一个静态方法向外界提供这个类的实例
    public static Singleton getInstance(){
       return instatnce;
    }
    }
    
    方法二
    public class Singleton2{
    private static Singleton2 instance2=null;
    public static synchronized Singleton2 getInstance(){
       if(instance2==null)
       instatce2=new Singleton2();
       return instance2;
    }
    }
    

    synchronized :/'sɪŋkrənaɪzd/ :Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。

    • 当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
    • 然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
    • 尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。
    • 第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。
    • 以上规则对其它对象锁同样适用.

    注:这二个方法实现了一样的功能,但个人推荐采用第一种方法。

    二、工厂模式

    该模式主要功能是统一提供实例对象的引用。看下面的例子:

    public class Factory{
      public ClassesDao getClassesDao(){
        ClassesDao cd = new ClassesDaoImpl();
        return cd;
      }
    }
    
    interface ClassesDao{
       public String getCLassesName();
    }
    
    class ClassesDaoImpl implements ClassesDao{
       public String getClassesName(){
         System.out.println("A班");
      }
    }
    
    class test{
      public static void main(String[] args){
        Factory f=new Factory();
        f.getClassesDao().getClassesName();
      }
    }
    

    这个是最简单的例子了,就是通过工厂方法通过接口获取对象的引用

    三、建造模式

    该模式其实就是说,一个对象的组成可能有很多其他的对象一起组成的,比如说,一个对象的实现非常复杂,有很多的属性,而这些属性又是其他对象的引用,可能这些对象的引用又包括很多的对象引用。封装这些复杂性,就可以使用建造模式。

    定义:

    建造者模式:将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

    实用范围:
    1. 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
    2. 当构造过程必须允许被构造的对象有不同表示时。
    角色:

    在这样的设计模式中,有以下几个角色:

    1. Builder:为创建一个产品对象的各个部件指定抽象接口。
    2. ConcreteBuilder:实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并提供一个检索产品的接口。
    3. Director:构造一个使用Builder接口的对象,指导构建过程。
    4. Product:表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
    角色Builder:
    public interface PersonBuilder{
      void builderHead();
      void buildBody();
      void buildFoot();
      Person buildPerson();
    }
    
    角色ConcreteBuilder:
    public class ManBuilder implements PersonBuilder{
      Person person;
      public ManBuilder(){
         person = new Man();
      }
     public void buildbody(){
       person.setBody("创建男人的身体");
      }
    
      public void buildFoot(){
        person.setFoot("创建男人的脚");
      }
    
      public void buildHead(){
        person.setHead("建造男人的头");
      }
    
      public Person buildPerson(){
         return person;
        }
    }
    
    public class WomanBuilder implements PersonBuilder {  
    Person person;  
    public WomanBuilder() {  
         person = new Woman();  
     }  
    public void buildbody() {  
        person.setBody(“建造女人的身体");
     }  
    public void buildFoot() {  
        person.setFoot(“建造女人的脚");
     }  
    public void buildHead() {  
        person.setHead(“建造女人的头"); 
     }  
    public Person buildPerson() {  
        return person;  
     }  
    } 
    
    角色Director:
    public class PersonDirector{
      public Person constructPerson(PersonBuilder pb){
         pb.buildHead();
         pb.buildBody();
         pb.buildFoot();
         return pb.buildPerson();
       }
    }
    
    角色Product:
    public class Person {  
         private String head;  
         private String body;  
         private String foot;  
      
         public String getHead() {  
              return head;  
         }  
         public void setHead(String head) {  
              this.head = head;  
         }  
         public String getBody() {  
              return body;  
         }  
         public void setBody(String body) {  
              this.body = body;  
         }  
         public String getFoot() {  
              return foot;  
         }  
         public void setFoot(String foot) {  
              this.foot = foot;  
         }  
    }
    
    public class Man extends Person {  
         public Man(){  
              System.out.println(“开始建造男人");  
         }  
    }
    
    public class Woman extends Person {  
         public Woman(){  
              System.out.println(“开始建造女人");  
         }  
    } 
    
    测试
    public class Test{
      public static void main(String[] args){
        PersonDirector pd = new PersonDirector();
        Person manPerson=pd.constructPerson(new ManBuilder());
        Person womanPerson = pd.constructPerson(new WomanBuilder());
      }
    }
    

    建造者模式在使用过程中可以演化出多种形式:
    如果具体的被建造对象只有一个的话,可以省略抽象的Builder和Director,让ConcreteBuilder自己扮演指导者和建造者双重角色,甚至ConcreteBuilder也可以放到Product里面实现。
    在《Effective Java》书中第二条,就提到“遇到多个构造器参数时要考虑用构建器”,其实这里的构建器就属于建造者模式,只是里面把四个角色都放到具体产品里面了。
    上面例子如果只制造男人,演化后如下:

        public class Man {  
             private String head;  
             private String body;  
             private String foot;  
          
             public String getHead() {  
                  return head;  
             }  
             public void setHead(String head) {  
                  this.head = head;  
             }  
             public String getBody() {  
                  return body;  
             }  
             public void setBody(String body) {  
                  this.body = body;  
             }  
             public String getFoot() {  
                  return foot;  
             }  
             public void setFoot(String foot) {  
                  this.foot = foot;  
             }  
        }  
    
        public class ManBuilder{  
             Man man;  
             public ManBuilder() {  
                  man = new Man();  
             }  
             public void buildbody() {  
                  man.setBody("建造男人的身体");  
             }  
             public void buildFoot() {  
                  man.setFoot("建造男人的脚");  
             }  
             public void buildHead() {  
                  man.setHead("建造男人的头");  
             }  
             public Man builderMan() {  
                  buildHead();  
                  buildBody();  
                  buildFoot();  
                  return man;  
             }  
        }  
    
    测试:
    public class Test{  
         public static void main(String[] args) {  
              ManBuilder builder = new ManBuilder();  
              Man man = builder.builderMan();  
         }  
    }
    

    四、门面模式

    这个模式个人感觉像是Service层的一个翻版。比如Dao我们定义了很多持久化方法,我们通过Service层将Dao的原子方法组成业务逻辑,再通过方法向上层提供服务。门面模式道理其实是一样的。

    具体看看这个例子

    interface ClassesDao{
       public String getClassesName();
    }
    
    class CLassesDaoImpl imPlements ClassesDao{
      public String getClassesName(){
        return "A班";
     }
    }
    
    interface ClassesDao2{
     public String getClassesName2();
    }
    
    class ClassesDaoImple2 implementd ClassesDao2{
     public String getClassessName2(){
       return "B班";
     }
    }
    
    class ServiceManager{
     private ClassesDao cd = new ClassesDaoImpl();
     private ClassesDao2 cd2 = new ClassesDaoImpl2();
     public void printOut{
       System.out.println(cd.getClassesName()+"  " + cd2.getClassesName2());
     }
    }
    

    虽然这个例子不全,但基本意思已经很明显了。

    五、策略模式

    这个模式是将行为的抽象,即当有几个类有相似的方法,将其中通用的部分都提取出来,从而使扩展更容易。

    看这个例子:

    加法具体策略类
    public class Addition extends Operation {
    @Override
    public float parameter(float a, float b) {
       return a+b;
     }
    }
    
    除法具体策略类
    public class Division extends Operation {
    @Override
    public float parameter(float a, float b) {
       return a/b;
       }
    }
    
    乘法具体策略类
    public class Multiplication extends Operation{
    @Override
    public float parameter(float a, float b) {
       return a*b;
      }
    }
    
    减法具体策略类
    public class Subtration extends Operation {
    @Override
    public float parameter(float a, float b) {
       return a-b;
      }
    }
    
    抽象策略类也可以使用接口来代替
    public abstract class Operation {
       public abstract float parameter(float a, float b);
    }
    
    策略环境类
    public class Condition {
    
    public static final Addition add = new Addition();
    
    public static final Subtration sub = new Subtration();
    
    public static final Multiplication mul = new Multiplication();
    
    public static final Division div = new Division();
    
    }
    
    测试客户端
    public class Client {
    public static void main(String[] args) {
       float a = 100;
       float b = 25;
       System.out.println(Condition.div.parameter(a, b));
       }
    }
    

    相关文章

      网友评论

          本文标题:java常用设计模式

          本文链接:https://www.haomeiwen.com/subject/rltqzttx.html