一、 单例设计模式
- 单例设计模式:保证类在内存中只有一个对象。
- 如何保证类在内存中只有一个对象呢?
(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;
}
}
该方法有一定的缺陷,当多线程去访问的时候会有安全,会创建多个对象出来。
饿汉式和懒汉式的区别?
- 饿汉式是空间换时间(因为一上来就开辟内存空间),懒汉式是时间换取空间。(需要进行判断)
- 在多线程访问时,饿汉式不会创建多个对象,而懒汉式有可能会创建多个对象。
(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(模板)设计模式
- 模版设计模式概述
模版方法模式就是定义一个算法的骨架,而将具体的算法延迟到子类中来实现
- 优点和缺点
优点
- 使用模版方法模式,在定义算法骨架的同时,可以很灵活的实现具体的算法,满足用户灵活多变的需求
缺点
- 如果算法骨架有修改的话,则需要修改抽象类
案例(计算一段程序运行一段时间)
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();
}
}