Java基础---设计模式

 

设计模式

一、设计模式概述

1设计模式(Designpattern)是一套被反复使用、多数人知晓、经过分类编目和代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性

2、设计模式不是一种方法或技术,而是一种思想;

3、设计模式和具体的语言无关,学习设计模式就是要建立面向对象的思想,尽可能的面向接口编程,低耦合,高内聚,使设计的程序可复用;

4、学习设计模式能够促进对面向对象思想的理解,反之亦然;它们相辅相成。

二、设计模式的要素

1、名字:必须有一个简单,有意义的名字;

2、问题:描述在何时使用模式;

3、解决方案:描述设计的组成部分以及如何解决问题;

4、效果:描述模式的效果以及优缺点。

三、设计模式的分类

1、创建型模式:对象的创建;

2、结构型模式:对象的组成(结构)

3、行为型模式:对象的行为

四、常见的设计模式

1、工厂模式

      (1)简单工厂模式

                又叫静态工厂方法模式,它定义一个具体的工厂类负责创建一些类的实例。

实例:

//简单工厂模式演示
public class SimpleFactory {
	public static void main(String[] args) {
		// 之前创建实例对象的方法:
		Student s = new Student();
		Teacher t = new Teacher();

		// 使用工厂模式,对象由工厂类创建:
		s = (Student) new PersonFactory().createPerson("Student");
		t = (Teacher) new PersonFactory().createPerson("Teacher");

		s.eat();// 吃饭
		t.teaching();// 授课
	}

}

// 人类抽象类
abstract class Person {
	public abstract void eat();
}

// 具体学生类
class Student extends Person {
	public void study() {
		System.out.println("学习");
	}

	@Override
	public void eat() {
		System.out.println("吃饭");
	}
}

// 具体教师类
class Teacher extends Person {
	public void teaching() {
		System.out.println("授课");
	}

	@Override
	public void eat() {
		System.out.println("吃饭");
	}
}

/*
 * 开始,在测试类中每个具体的内容自己创建对象,但是,创建对象的工作如果比较麻烦, 就需要有人专门做这个事情,所以就制造了一个专门的类来创建对象。
 */
class PersonFactory {
	public static Person createPerson(String personName) {
		if ("Student".equals(personName)) {
			return new Student();
		} else if ("Teacher".equals(personName)) {
			return new Teacher();
		} else {
			return null;
		}
	}
}

 

总结:简单工厂模式优点是客户端不需要再负责对象的创建,从而明确了各个类的职责;缺点是这个工厂类负责所有对象的创建,如果有新的对象增加,或者某些对象的创建方式不同,就需要不断的修改工厂类,不利于后期的维护,于是改进为工厂方法模式。

     (2)工厂方法模式

             工厂方法模式中抽象工厂类负责定义创建对象的接口,具体对象的创建工作由继承抽象工厂的具体类实现。

实例:

//创建工厂方法模式的演示类
public class FactoryFunction {
	public static void main(String[] args) {
		// 之前创建实例对象的方法:
		Student s = new Student();
		Teacher t = new Teacher();

		// 使用工厂模式,对象由工厂类创建:
		s = (Student) new PersonFactory().createPerson("Student");
		t = (Teacher) new PersonFactory().createPerson("Teacher");

		s.study();// 学习
		t.eat();// 吃饭
	}
}

// 工厂接口
interface Factory {
	public abstract Person createPerson(String personName);
}

// 学生工厂
class StudentFactory implements Factory {

	@Override
	public Person createPerson(String personName) {
		if ("Student".equals(personName)) {
			return new Student();
		} else {
			return null;
		}
	}

}

// 教师工厂
class TeacherFactory implements Factory {

	@Override
	public Person createPerson(String personName) {
		if ("Teacher".equals(personName)) {
			return new Student();
		} else {
			return null;
		}
	}

}

总结:

       优点:客户端不需要再负责对象的创建,从而明确了各个类的职责,如果有新的对象增加,只需要增加一个具体的类和具体的工厂类即可,不影响已有的代码,后期维护容易,增强了系统的扩展性,这就是设计模式的开闭原则。

       缺点:需要额外的编写代码,增加了工作量。

2、单例模式

     单例模式就是要确保类在内存中只有一个对象,该实例必须自动创建,并且对外提供。通过构造方法私有化避免在类的外部实例化,调用方法访问该实例,一般两种方案。

          (1)饿汉式:类被加载时创建实例,线程安全,一般用本方法。

public class Singleton {
	private Singleton() {// 构造函数私有化,与实例调用方法一起确保实例唯一

	}

	// 类加载时自行实例化
	private static final Singleton instance = new Singleton();

	// 通过工厂方法调用本类实例
	public static Singleton getInstnce() {
		return instance;
	}

}
             (2)懒汉式:实例在工厂方法内创建,此时存在线程安全问题,可加同步锁解决。                 
public class Singleton {
	private Singleton() {// 构造函数私有化,与实例调用方法一起确保实例唯一

	}

	// 定义一个Singleton变量,与饿汉式不同的是该变量还没有初始化,另外不加final,否则该变量不能改变
	private static Singleton instance = null;

	// 通过工厂方法调用本类实例
	public static synchronized Singleton getInstnce() {
		if (instance != null) {
			return instance;
		} else {
			return new Singleton();
		}

	}

}
总结:
       单例模式优点是在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象单例模式无疑可以提高系统的性能;缺点是没有抽象层,因此扩展很难,职责过重,在一定程序上违背了单一职责
 
3、模版设计模式
       模版方法模式就是定义一个算法的骨架,而将具体的算法延迟到子类中来实现,比如我要知道一段代码的运行时间,可以在这段代码前后加上System.currentTimeMillis()获取执行前和执行后的时间再相减得到程序执行时间,为了方便计算其它代码的执行时间,我们把这段代码抽象到code()方法中,到用时再去定义或重写,将需运行的程序加进code()方法中,像线程中的run方法一样
 
public abstract class GetTime {
	// 需求:请给我计算出一段代码的运行时间
	public long getTime() {
		long start = System.currentTimeMillis();
		
		code();

		long end = System.currentTimeMillis();

		return end - start;
	}

	public abstract void code();
}
总结:
       模版设计模式的优点是在定义算法骨架的同时,可以很灵活的实现具体的算法,满足用户灵活多变的需求;缺点是如果算法骨架有修改的话,则需要修改抽象类
 
4、装饰设计模式
      装饰模式就是使用被装饰类的一个子类的实例,在客户端将这个子类的实例交给装饰类;是继承的替代方案。个人理解一般就是将一个类通过参数传递的方式传给装饰类,然后获得装饰类的新功能,例如我们常见的IO操作就运用了装饰设计模式:
// 想想我们在IO流中的使用
		InputStream is = System.in;//新建一个InputStream类的实例is,将System.in赋值给is
		//将is传递给装饰类InputStreamReader装饰,变成字符流
		InputStreamReader isr = new InputStreamReader(is);
		//字符流对象isr再传递给装饰类BufferedReader变成缓冲流
		BufferedReader br = new BufferedReader(isr);
		//一般到位将InputStream对象装饰成BufferedReader对象
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		//一步到位将OutputStream对象装饰成BufferedWriter对象
		BufferedWriter bw = new BufferedWriter((new OutputStreamWriter(
				System.out)));

		Scanner sc = new Scanner(System.in);
 
总结:
       优点:使用装饰模式,可以提供比继承更灵活的扩展对象的功能,它可以动态的添加对象的功能,并且可以随意的组合这些功能。
        缺点:正因为可以随意组合,所以就可能出现一些不合理的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值