JAVA常用设计模式

很多人在学习设计模式,感觉定义很抽象,包括我,这也难怪JAVA本来就是一种抽象的思想,所以写了这篇博客,加入我自己的理解,难免会有一些不合理的地方,希望大家批评指正。
首先说说设计模式是什么吧。简单的来说,设计模式是一个经验的总结,与具体的语言无关,相当于一个模型,可以被不同的语言反复使用,本文以JAVA语言为基础。

一、要明白具体的设计模式,我们就需要知道设计模式做了什么,具体原则是什么

 1. 单一职责:简单的说,就是每个类需要做的事情尽量少,最好是一件
 2. 开闭原则:把经常变得东西抽象成一个模板,变化的部分只提供一个方法,具体的细节由子类实现,即别人想添加功能,只需要添加一个子类,而无需修改源码的实现。
 3. 里氏替换:这个我们应该很熟悉,就是一种继承的理念,即继承父类的子类们中,应该具有一些共同的行为特征和属性,比如不能定义一个Person类,让Pig继承。
 4. 依赖注入原则:也是一种分离思想,即子类对象依赖于抽象类,而不是依赖具体实现类
 5. 接口分离原则:一个接口的功能要满足单一原则,因为接口的实现,必须重写接口的方法,所以接口的抽象方法不宜过多。
 6. 迪米特原则:对象与对象之间的关系要少,比如一个对象尽量不要去调用另一个对象的方法。
 7. 总结,虽然是用自己的话在表述,但自己也不知道自己在写什么。

二、接下来,我想介绍一些常用的设计模式

█ 简单工厂设计模式:类的创建由工厂类去实现,比如我需要实现一个水果工厂,别人需要什么水果,我就提供什么

第一步:创建工厂类
public class FruitFactory {

    public static Fruit createFruit(String fruitType)
    {
        if("apple".equals(fruitType)){
            return new Apple();
        }else if("banana".equals(fruitType))
        {
            return new Banana();
        }else{
            return null;
        }
    }
}
第二步:水果接口
public abstract class Fruit {
    public abstract void taste();
}
第三步:创建需要添加的具体水果
 1. 造苹果
public class Apple extends Fruit {

    @Override
    public void taste() {
        // TODO Auto-generated method stub
      System.out.println("苹果味道有点酸!");
    }
}
2. 造香蕉
public class Banana extends Fruit {

    @Override
    public void taste() {
        // TODO Auto-generated method stub
      System.out.println("香蕉味道很甜!");
    }
}
第四步:具体实现造水果
public class FruitDemo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Fruit fruit = FruitFactory.createFruit("apple");//要苹果?造一个!
        fruit.taste();
        a = AnimalFactory.createAnimal("banana");//要香蕉?造一个!
        fruit.taste();
    }
}
 第五步:总结

从上面的代码,得知,水果工厂内只有apple和banana,但如果客户需要橘子,怎么办?这还不简单?so easy。
public class FruitFactory {

    public static Fruit createFruit(String fruitType)
    {
        if("apple".equals(fruitType)){
            return new Apple();
        }else if("banana".equals(fruitType))
        {
            return new Banana();
        }else if("orange".equals(fruitType))
        {
            return new Orange();
        else{
            return null;
        }
    }
}
 但还需要橙子,梨子,桃子呢?所以缺点总结如下
       1. 有新的需求,工厂类就必须不断修改,麻烦!所以出现了工厂类。下面介绍工厂类。

█ 工厂模式:在简单工厂类的基础上,添加了小工厂,就好像有一个水果工厂,还添加一个子工厂,专门造苹果,另一个子工厂专门造香蕉,这样,新的需求只需添加一个需求类实现水果工厂接口即可,废话不多说,看代码。

  第一步:创建大工厂类接口
public interface Factory {
    public abstract Fruit createFruit();
}
第二步:创建水果类
public abstract class Fruit {
    public abstract void taste();
}
第三步:创建具体水果的小工厂类,实现大工厂接口
 1. 苹果工厂
public class AppleFactory implements Factory {

    @Override
    public Fruit createFruit() {
        // TODO Auto-generated method stub
        return new Apple();
    }
}
2. 香蕉工厂
public class BananaFactory implements Factory {

    @Override
    public Fruit createFruit() {
        // TODO Auto-generated method stub
        return new Banana();
    }
}
第四步:造水果,继承水果类


 1. 造苹果
public class Apple extends Fruit {
    @Override
    public void taste() {
        // TODO Auto-generated method stub
        System.out.println("苹果味道有点酸!");
    }

}
  1. 造香蕉
public class Banana extends Fruit {

    @Override
    public void taste() {
        // TODO Auto-generated method stub
      System.out.println("香蕉味道很甜!");
    }
}
第五步:测试类
public class FruitDemo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //苹果
         Factory factory = new AppleFactory();
         Fruit fruit = factory.creatFruit();
         System.out.println(fruit.taste);

         //香蕉
         factory = new BananaFactory();
         Fruit fruit = factory.creatFruit();
         System.out.println(fruit.taste);
    }
}
第六步:总结   

优点:每增加一个需求,只需增加一个具体类,和具体类的工厂类,而无需改动原有的代码。
缺点:工作量较大,看着都累。

█ 单例设计模式:简单的来说,就是不允许外部创建对象,而是直接使用,那么如何实现不让外界创建对象,而且还可以使用对象呢?
- 将被使用类的构造方法私有化,即private修饰
- 在类的成员位置创建对象
- 创建公有方法getObject,让外界能够使用

  • 单例设计模式——-饿汉式:就是立即创建对象
public class Fruit {

     private Fruit()
     {
     //构造方法使用private修饰
     }
     //创建Fruit对象
     static Fruit fruit = new Fruit();
     //通过公有属性方法返回对象给外界
     public static Fruit getFruit()
     {
         return fruit;
     }
}
测试
public class FruitDemo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Fruit.fruit = null;
        Fruit fruit = Fruit.getFruit();
    }
}
  • 单例设计模式——-懒汉式:不立即创建对象,而是延后到被调用时
public class Fruit {

     private Fruit()
     {
     //构造方法使用private修饰
     }
     //创建Fruit对象
     static Fruit fruit = null;
     //通过公有属性方法返回对象给外界
     public static Fruit getFruit()
     {
         if(fruit == null)
         {
         fruit = new Fruit();
         }
         return fruit;
     }
}
测试
public class FruitDemo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Fruit.fruit = null;
        Fruit fruit = Fruit.getFruit();
    }
}
  • 单例设计模式——总结
    在实际应用中会选择饿汉式,因为懒汉式存在安全隐患,在多线程时,多个线程同时获取该对象时,会出现对象具体的创建混乱。解决办法如下:同步方法。
public class Fruit {

     private Fruit()
     {
     //构造方法使用private修饰
     }
     //创建Fruit对象
     static Fruit fruit = null;
     //通过公有属性方法返回对象给外界,注意添加synchronized,实现线程的同步
     public synchronized static Fruit getFruit()
     {
         if(fruit == null)
         {
         fruit = new Fruit();
         }
         return fruit;
     }
}

█ 模版设计模式:定义一个算法的骨架,这个骨架就是一个模版,具体的算法实现推迟到子类中,比如我们计算算法运行的效率,我们就可以把计算效率提取成一个模版,而具体的算法我们可以到子类中实现,而无需改动模版。

 第一步:定义一个模版 
public abstract class Pattern {
    public long getTime(){
        long startTime = System.currentTimeMillis();
        methodPattern();//只需实现这个抽象方法来实现具体的算法即可
        long endTime = System.currentTimeMillis();      
        return endTime-startTime;
    }
    public abstract void methodPattern();
}
第二步:实现具体的算法,这里选择快速排序,其他的就不一一举例
public class ForTest extends Pattern {

    //排序
        public static void Sort(int[] arr,int low,int high)
        {
            if(low < high)
            {
                int position = getPositionSort(arr,low,high);
                Sort(arr,low,position-1);
                Sort(arr,position+1,high);
            }
        }
        private static int getPositionSort(int[] arr, int low, int high) {
            // TODO Auto-generated method stub
            int temp = arr[low];
            while(low < high)
            {
                while(low < high && arr[high]>temp)
                    high--;
                arr[low] = arr[high];
                while(low < high && arr[low] < temp)
                    low++;
                arr[high] = arr[low];
            }
            arr[low] = temp;
            return low;
        }
        //主要是这个构造方法的重写
    @Override
    public void methodPattern() {
        // TODO Auto-generated method stub
        int arr[] = {12,3,2,30,10};

        Sort(arr,0,arr.length-1);
        for(int s_arr:arr)
        {
            System.out.print(s_arr+" ");
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值