黑马程序员——设计模式

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

设计模式

概念

设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代 码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决 方案,这也是它能被广泛应用的原因。

设计模式的类型
创建型模式共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

设计模式的原则

  • 1.开闭原则:对扩展开发,对修改关闭。

  • 2.里氏代原则:任何基类出现的地方,子类一定可以出现。

  • 3.依赖倒转原则:对应接口编程,依赖于抽象而不依赖于具体。

  • 4.接口隔离原则:使用多个隔离接口,比使用单个好。

  • 5.迪米特法则:尽量让功能模块相对独立。

  • 6.合成复用原则:尽量使用合成\聚合的方式,而不是继承。

1工厂设计模式
普通工厂模式:建一个工厂类,对实现了同一接口的类进行实例化创建。
示例代码:

package ShejimoshiDemo;
interface Produce  //创建生产接口。
{
    public void produce();
}
class carProduce implements Produce  //创建汽车的生产实现了生产接口。
{
    public void produce()
    {
        System.out.println("汽车生产");
    }
}
class bicycleProduce implements Produce  //创建自行车车的生产实现了生产接口。
{
    public void produce()
    {
        System.out.println("自行车车生产");
    }
}
class factory  //创建专门生产的工厂,根据要传入的生产类型,创建对应的生产类。
{
    public Produce facProduce(String str)
    {
        if(str.equals("car"))  //汽车的生产
        {
             return new carProduce();  //创建汽车生产的对象。
        }
        else if(str.equals("bicycle"))  //自行车生产
            return new bicycleProduce();  //创建自行车生产对象。
        else
            return null;
    }
}
public class ShejimoshiDemo1
{
    public static void main(String[] args)
    {
        factory fac = new factory();  //建立一个工厂。
        Produce pro = fac.facProduce("car");  //传入要生产的类型。获得生产类型的对象。
        pro.produce();  //调用生产。
    }
}
多个工厂方法模式:工厂类多个方法分别创建相对应的实例。

示例代码:

package ShejimoshiDemo;
interface Produce  //创建生产接口。
{
    public void produce();
}
class carProduce implements Produce  //创建汽车的生产实现了生产接口。
{
    public void produce()
    {
        System.out.println("汽车生产");
    }
}
class bicycleProduce implements Produce  //创建自行车车的生产实现了生产接口。
{
    public void produce()
    {
        System.out.println("自行车车生产");
    }
}
class factory  //创建专门生产的工厂,根据要传入的生产类型,创建对应的生产类。
{
    public Produce carproduce()  //创建汽车生产的实例。
    {
        return new carProduce();
    }
    public Produce bicycleproduce()  //创建自行车生产的实例。
    {
        return new bicycleProduce();
    }
}
public class ShejimoshiDemo1
{
    public static void main(String[] args)
    {
        factory fac = new factory();  //建立一个工厂。
        Produce pro = fac.bicycleproduce();  //调用要生产的类型。获得生产类型的对象。
        pro.produce();  //调用生产。
    }
}
静态工厂方法模式:将工厂方法模式设置为静态,不需要创建工厂实例。

示例代码:

package ShejimoshiDemo;
interface Produce  //创建生产接口。
{
    public void produce();
}
class carProduce implements Produce  //创建汽车的生产实现了生产接口。
{
    public void produce()
    {
        System.out.println("汽车生产");
    }
}
class bicycleProduce implements Produce  //创建自行车车的生产实现了生产接口。
{
    public void produce()
    {
        System.out.println("自行车车生产");
    }
}
class factory  //创建专门生产的工厂,根据要传入的生产类型,创建对应的生产类。
{
    public static Produce carproduce()  //创建汽车生产的实例。
    {
        return new carProduce();
    }
    public static Produce bicycleproduce()  //创建自行车生产的实例。
    {
        return new bicycleProduce();
    }
}
public class ShejimoshiDemo1
{
    public static void main(String[] args)
    {
        Produce pro = factory.bicycleproduce();  //调用要生产的类型。获得生产类型的对象。
        pro.produce();  //调用生产。
    }
}
抽象工厂模式:创建多个工厂类,对应相应的生产类型。
示例代码:

package ShejimoshiDemo;
interface Produce  //生产接口。
{
    public void produce();
}
interface Provider  //工厂接口。
{
    public Produce produce();
}
class CarProduce implements Produce  //汽车生产实现了生产接口。
{
    public void produce()
    {
        System.out.println("汽车生产");
    }
}
class BicycleProduce implements Produce  //自行车生产实现了生产接口。
{
    public void produce()
    {
        System.out.println("自行车生产");
    }
}
class CarFactory implements Provider  //汽车工厂实现了工厂接口。
{
    public Produce produce()
    {
        return new CarProduce();
    }
}
class BicycleFactory implements Provider  //自行车工厂实现了工厂接口。
{
    public Produce produce()
    {
        return new BicycleProduce();
    }
}
public class ShejimoshiDemo2
{
    public static void main(String[] args)
    {
        Provider p = new CarFactory();  //创建要生产的对应类型的工厂
        Produce pro = p.produce();  //创建生产的对象。
        pro.produce();  //对象进行生产。
    }
}
 2单例设计模式
  保证该对象只有一个实例存在。
 单例设计模式有两种:
 懒汉式:先创建对象,延迟初始化(多线程需要用锁解决安全问题)。
 饿汉式:创建对象的时候就初始化。

 示例代码:
package ShejimoshiDemo;
class Single_1  //懒汉式,延迟加载。
{
    private static Single_1 s = null;  //创建对象实例,进行为null的初始化。
    private Single_1() //私有构造函数,无法new对象实例,从而做到单例。
    {
    }
    public static Single_1 getInstance()  //多线程存在安全隐患,所以加锁。
    {
        if(s==null)  //只有第一次创建的时候才需要加锁,用双if判断可以减少加锁的次数,提高程序性能。
        {
            synchronized (s)
            {
                if(s==null)
                {
                    return s = new Single_1();  //对实例进行赋值。
                }
            }
        }
        return s;
    }
}
class Single_2  //饿汉式
{
    private static Single_2 s = new Single_2();  //创建该类的对象实例,并初始化。
    private Single_2()  //私有构造函数,无法new对象实例,从而做到单例。
    {}
    public static Single_2 getInstance()  //返回实例对象。
    {
        return s;
    }
}
public class SingleDemo
{
    public static void main(String[] args)
    {
        //获取实例对象
        Single_1.getInstance();
        Single_2.getInstance();
    }
}
3装饰设计模式

装饰设计模式就是在对原有类的某些功能进行实际上的增强产生的设计模式。

示例代码:

package ShejimoshiDemo;
import java.io.*;
/**设计模式
 * 将某个对象的某个方法进行功能增强。
 * 装饰类中功能底层还是调用的被装饰类对象的功能,只是在原有对象的功能基础上对功能进行增强。
 * 模拟字符缓冲区输入流BufferedReader
 * MyBufferedReader为装饰类。
 * Reader为被装饰类
 * */
class MyBufferedReader
{
    private Reader bin;
    public MyBufferedReader(Reader in)
    {
        this.bin =in;
    }
    public String readLine() throws IOException  //模拟BufferedReader的readLine方法。
    {
        int length;
        char[] buff = new char[1024]; //创建接收字符的字符数组
        int pos = 0;  //字符数组的索引值
        Boolean flag = false; //创建换行识别标记
        while((length=bin.read())!=-1)  //用Reader的read单个读取字符。
        {
            char c = (char)length; //把返回的字符值转换为字符。
            if(c=='\r') //判断返回的字符是否为'\r'。是的话把换行识别标记置为true。
            {
                flag = true;
            }
            else if (c=='\n' && flag==true)  //判断字符是否换行标记符的'\n',并且满足换行标记为true,两个条件都满足的话就意味一行的结尾。
            {
                
                return new String(buff, 0, pos);  //返回字符数组中的字符,组成一个字符串为一行。
            }
            else
            {
                buff[pos] = c;  //字符不是\r和\n,就加入到字符数组中。
                pos++;  //字符数组的索引+1。
            }
        }
        return null; //循环结束意味到了文件末尾,所以返回null。
    }
    public void close() throws IOException
    {
        bin.close();  //关闭流对象。
    }
}
public class DecorateDemo
{
    public static void main(String[] args) throws IOException
    {
        FileReader f = new FileReader("/DemoTest/src/ShejimoshiDemo/SingleDemo.java");  //读取文件。
        MyBufferedReader my = new MyBufferedReader(f);  //用定义的缓冲区来读取文件。
        String line;
        while ((line=my.readLine()) != null)  //读取一行字符串,返回null意味文件读取完毕。
        {
            System.out.println(line);  //打印一行字符组成的字符串。
        }
        my.close();  //关闭流对象。
    }
}

你可能感兴趣的:(java学习笔记)