java中的设计模式可以简单分为,创建型模式 对象的创建,结构型模式 对象的组成(结构),行为型模式 对象的行为 ,而其中在javase比较常用的也是很重要的就是静态工厂模式以及单例模式。
一、静态工厂模式
1、静态工厂模式可以理解为提供了一个工厂,里面不停的制造一些需要的对象,所以静态工厂模式里面需要提供一个工厂类。
该方法的特点是,它的构造方法要私有化,外界不能直接创建它的对象,然后提供静态方法,该方法产生所需要的对象
但该方法也是有缺点的,它的缺点就是不利于后期的维护,因为。如果要添加新的对象,需要创建它的类还需要在静态工厂类中提供一些功能,要不停的修改工厂类。
上面所说的应该怎么理解呢,下面附上一个例子进行说明。就用猫和狗的例子进行说明
//这是一个动物抽象类
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("狗吃肉...");
}
}
//这是一个工厂类,可以看出该类的构造方法进行了私有,然后类中提供了一个createAnimal静态方法,用来提供所需要的猫和狗的对象,这里利用了多态。
public class AnimalFactory {
//私有功能
private AnimalFactory(){
}
//:提供猫和狗这两种动物
public static Animal createAnimal(String type){
if("dog".equals(type)){
return new Dog() ;
}else if("cat".equals(type)){
return new Cat() ;
}else {
return null ;
}
}
}
//这是一个测试类,里面分别给出了在没有使用静态工厂时和使用了静态工厂时创建对象的方法。
public class AnimalDemo {
public static void main(String[] args) {
//没有使用静态工厂方法模式:普通的方式
Dog d = new Dog() ;
d.eat() ;
Cat c = new Cat() ;
c.eat() ;
System.out.println("-----------------------");
//改进之后
Animal a = AnimalFactory.createAnimal("dog") ;
a.eat() ;
a = AnimalFactory.createAnimal("cat") ;
a.eat() ;
a = AnimalFactory.createAnimal("pig") ;
if(a!=null){
a.eat() ;
}else{
System.out.println("目前工厂类没有提供该动物...");
}
}
}
从上面的例子可以看出,当需要创建动物类对象的时候,可以生成一个类继承动物类,然后对静态工厂进行修改,增添所需要的功能。
但是每次增加动物类的时候,都要去修改工厂类,这就不利于后期的维护,所以有了下面的这种模式,工厂方法模式。
2、工厂方法模式
这种模式就是为了解决上面的静工厂模式的缺点所提出来的,该方法的特点是:
需要提供一个抽象类,以及每个动物的具体类和接口(工厂接口),该接口中的抽象方法的返回值是该抽象类针对每个具体动物都提供一些对应的工厂类,但是缺点就是增加了代码量,下面改进一下上面的算法进行说明。
//开始还是提供三个类
//这是一个动物抽象类
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 abstract Animal createAnimal() ;
}
//然后分别提供两个猫和狗的工厂类,分别实现工厂类接口,重写抽象方法。
//猫的工厂类
public class CatFactory implements Factory {
//由猫工厂类提供对象
@Override
public Animal createAnimal() {
return new Cat() ;
}
}
//狗的工厂类
public class DogFactory implements Factory {
//由狗的工厂类提供它的对象
@Override
public Animal createAnimal() {
return new Dog() ;
}
}
//这是一个测试类
public class AnimalDemo {
public static void main(String[] args) {
//需求:我要养一只狗
Factory f = new DogFactory() ;
Animal a = f.createAnimal() ; //new Dog() ;
a.eat() ;
System.out.println("--------------");
//养一只猫
f = new CatFactory() ;
a = f.createAnimal() ;
a.eat() ;
}
}
这个设计模式可以看出,当需要增加一个动物类的时候,只需要增加一个相应的工厂类和动物类继承动物类和实现工厂接口就行了,就不用再去修改工厂类了,这就符合了java的设计思想,“高内聚,低耦合”,但是也可以看出相应的代码量变的比较大了。
二、单例模式
单例模式的特点就是在内存中始终只有一个对象,它也有两种实现方式,饿汉式和懒汉式
饿汉式:
特点:当前某一个类一加载,就会创建一个对象。它需要将该类的无参构造私有化,在成员变量创建该类的实例,然后提供公共访问方法
例:
public class Student {
//无参构造私有化,目的是为了让外界不创建对象
private Student(){
}
//在成员变量的位置创建该类的实例
//静态只能访问静态,所以需要加上静态修饰
//为了不让外界修改当前这个实例,所以加入private修饰
private static Student s = new Student() ;
//提供给公共的访问方法,返回值就是该类的实例对象
public static Student getStudent(){
return s ;
}
}
懒汉式:
特点:并不是加载某一个类就直接创建对象,而是需要的时候再创建对象
例:
public class Teacher {
private Teacher(){}
//在成员变量位置声明变量
private static Teacher t = null ; //共享数据
//提供公共的方法访问
public synchronized static Teacher getTeacher(){ //Teacher.class锁对象
//判断 当当前该对象没有更多引用的时候,才创建对象
//t1,t1 ,t3 三个对象
if(t==null){
t = new Teacher() ;
}
return t ;
}
}
但是懒汉式设计模式有线程安全问题,会出现抢占线程的情况,所以加入 了同步锁synchronized 来解决。