JAVA基础——设计模式(单例设计模式,装饰设计模式,模板设计模式,简单工厂模式,工厂方法模式)

一、 单例设计模式

  • 单例设计模式:保证类在内存中只有一个对象。
  • 如何保证类在内存中只有一个对象呢?
    (1)控制类的创建,不让其他类来创建本类的对象。也就是让构造方法私有化。
    private
    (2)在本类中定义一个本类的对象。
    Singleton s;
    (3)提供公共的访问方式。
    public static Singleton getInstance(){return s}
  • 单例写法两种:
    (1)饿汉式 开发用这种方式
	public static void main(String[] args) {
    
    
		/*
		 * Singleton s1=Singleton.s; 
		 * Singleton.s =null; 
		 * Singleton s2=Singleton.s;
		 * //如果下面设置public属性,
		 * 此时两个对象一个是调用了Single的成员变量,
		 * 一个是设置成了null。这样对象会进行修改
		 */	
		//使用饿汉式创建对象,此时我们才分为一个对象
		Singleton s1=Singleton.getSingleton();
		Singleton s2=Singleton.getSingleton();
		System.out.println(s1==s2);
	}
class  Singleton{
    
    
	//1.私有构造方法,其他类不能访问该构造方法
	private Singleton() {
    
    }
	//2.创建本类对象,如果该处使用public方式的话,会出现
	private static Singleton s =new Singleton();
	//3.对外提供公共访问发给发
	public static Singleton getSingleton() {
    
    		
//获取实例
		return s;
	}
}

输出结果为:True。因为此时为同一个对象。

(2)懒汉式 面试写这种方式
先不去创建对象,只有用户需要的时候才进行创建。目的是为了节省空间

class Singleton{
    
    
	//懒汉式,单例的延迟加载模式
	//1,私有构造函数
	private Singleton () {
    
    }
	//2,声明一个本类的引用
	private static Singleton s;
	//3,对外提供公共的访问方法
	public static Singleton getSingleton() {
    
    
		if (s==null) {
    
    
			s=new Singleton();
		}
		return s;
	}
	
}

该方法有一定的缺陷,当多线程去访问的时候会有安全,会创建多个对象出来。

饿汉式和懒汉式的区别?

  1. 饿汉式是空间换时间(因为一上来就开辟内存空间),懒汉式是时间换取空间。(需要进行判断)
  2. 在多线程访问时,饿汉式不会创建多个对象,而懒汉式有可能会创建多个对象。

(3)第三种方式:
目的很明确,我们只要不改变s的值就可以了

	class Singleton {
    
    
	private Singleton() {
    
    }
	public static final Singleton s = new Singleton();
//final是最终的意思,被final修饰的变量不可以被更改
}

二、 装饰设计模式

public static void main(String[] args) {
    
    
		// TODO Auto-generated method stub
		SmartStudent smartStudent =new SmartStudent(new Student());
		smartStudent.code();
	}
	
}

interface Coder{
    
    
	public void code();
}

class Student implements Coder{
    
    
	@Override
	public void code() {
    
    
		System.out.println("JavaSE");
	}
}
class SmartStudent implements Coder{
    
    
	//1.获取被装饰类的引用
	private Student student;
	//2.在构造方法中传入被装饰类的对象
	public SmartStudent(Student student) {
    
    
		this.student = student;			//获取学生引用
	}
	//3.对原有的功能进行升级
	@Override
	public void code() {
    
    
		student.code();
		System.out.println("数据库");
		System.out.println("SSH");
	}	

装饰设计模式的好处是:耦合性不强,被装饰的类的变化与装饰类的变化无关

三、Template(模板)设计模式

  1. 模版设计模式概述

模版方法模式就是定义一个算法的骨架,而将具体的算法延迟到子类中来实现

  1. 优点和缺点

优点

  • 使用模版方法模式,在定义算法骨架的同时,可以很灵活的实现具体的算法,满足用户灵活多变的需求

缺点

  • 如果算法骨架有修改的话,则需要修改抽象类
    案例(计算一段程序运行一段时间)
public class Demo1_Template {
    
    

	public static void main(String[] args) {
    
    
		Demo demo =new Demo();
		System.out.println(demo.getTime());
	}
}

abstract class GetTime{
    
    
	public final long getTime() {
    
    
		long start=System.currentTimeMillis();
		Code();
		long end=System.currentTimeMillis();
		return end-start;
	}
	public abstract void Code();
}

class Demo extends GetTime{
    
    

	@Override
	public void Code() {
    
    
		for (int i = 0; i < 100000; i++) {
    
    
			System.out.println("x");
		}
		
	}
}

四. 简单工厂模式

又叫静态工厂方法模式,它定义一个具体的工厂类负责创建一些类的实例
优点:
客户端不需要在负责对象的创建,从而明确了各个类的职责
缺点:
这个静态工厂类负责所有对象的创建,如果有新的对象增加,或者某些对象的创建方式不同,就需要不断的修改工厂类,不利于后期的维护

案例:
第一步:创建接口

public abstract class Animal {
    
    
	public abstract void eat();
}

第二步:书写猫,狗类去实现动物接口的方法

public class Dog extends Animal {
    
    
	@Override
	public void eat() {
    
    
		System.out.println("狗吃肉");
	}
}
public class Cat extends Animal {
    
    
	@Override
	public void eat() {
    
    
		System.out.println("猫吃鱼");
	}
}

第三步:实现工厂(用户创建对象)

public class AnimalFactory {
    
    
//用于创建对象
	//public static Dog createDog() {
    
    
	//	return new Dog();
	//}
	//public static Cat createCat() {
    
    
	//	return new Cat();
	//}
	//但是该工厂会定义很多方法,需要创建很多对象。复用性太差
	//改进2.0版本
	public static Animal createAnimal(String name) {
    
    
		if ("dog".equals(name)) {
    
    
			return new Dog();
		}
		else if ("cat".equals(name)) {
    
    
			return new Cat();
		}else {
    
    
			return null;
		}
	}
}

第四步:做测试

public class Test {
    
    
	public static void main(String[] args) {
    
    
		//Dog d =AnimalFactory.createDog();
		Dog dog =(Dog) AnimalFactory.createAnimal("dog");
		dog.eat();
	}
}

简单工厂设计模式有个很明显的弊端,当我们没有工厂本该有的对象,会返回空对象,存在指针异常

五、工厂方法模式

概述:

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

优点

客户端不需要在负责对象的创建,从而明确了各个类的职责,如果有新的对象增加,只需要增加一个具体的类和具体的工厂类即可,不影响已有的代码,后期维护容易,增强了系统的扩展性

缺点

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

案例:
第一步:创建动物接口

public abstract class Animal {
    
    
	public abstract void eat();
}

第二步:创建实体类实现接口方法

public class Cat extends Animal {
    
    
	@Override
	public void eat() {
    
    
		System.out.println("猫吃鱼");
	}
}
public class Dog extends Animal {
    
    
	@Override
	public void eat() {
    
    
		System.out.println("狗吃肉");
	}
}

第三步:定义工厂方法

public interface Factory {
    
    
	public Animal createAnimal();
}

第四步:开工厂,实现猫工厂和狗工厂

public class CateFactory implements Factory {
    
    
	@Override
	public Animal createAnimal() {
    
    
		
		return new Cat();
	}
}
public class DogFactory implements Factory {
    
    
	@Override
	public Animal createAnimal() {
    
    
	
		return new Dog();
	}

}

做测试:

public class TEST {
    
    
	public static void main(String[] args) {
    
    
		DogFactory dogFactory =new DogFactory();
		Dog dog =(Dog) dogFactory.createAnimal();	
		dog.eat();
		
		CateFactory cateFactory =new CateFactory();
		Cat cat =(Cat) cateFactory.createAnimal();
		cat.eat();
	}
}

猜你喜欢

转载自blog.csdn.net/Mr_GYF/article/details/108980116