------- android培训、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;
- }
- }
- 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();
- }
- }
- }
- public abstract class GetTime {
- // 需求:请给我计算出一段代码的运行时间
- public long getTime() {
- long start = System.currentTimeMillis();
- code();
- long end = System.currentTimeMillis();
- return end - start;
- }
- public abstract void code();
- }
- // 想想我们在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);