javaSE (三十八)设计模式 ( 单例设计模式(饿汉式/懒汉式)、简单工厂模式、工厂模式、适配器模式、模板方法设计模式)

1、单例设计模式(饿汉式/懒汉式):

概念:保证类在内存中只有一个对象
思路:

  1. 私有构造方法,其他类不能再访问该构造方法了
  2. 创建本类对象(就在本类里创建),将对象的应用作为成员变量,并私有静态化(在这里又分为饿汉式和懒汉式,饿汉式直接引用连接对象,而懒汉式在第二步先创建引用,在第三步用一个判断语句,如果引用没有连接对象,就创建一个,如果有了,直接返回该引用
  3. 对外提供获取对象引用的方法getClass()

饿汉式和懒汉式的区别:

  • 饿汉式是空间换时间,懒汉式是时间换空间(不推荐)
  • 在多线程访问时,饿汉式不会创建多个访问对象,而懒汉式会(也就是说饿汉线程安全,懒汉不安全,可以加个同步锁synchronized)

代码实例:

package cn.xinhua;

public class ThreadTest {

	public static void main(String[] args) {
	
/*
 * 饿汉式
 */
class Singleton1 {
	// 1. 私有构造方法,其他类不能再访问该构造方法了
	private Singleton1() {
	}

	// 2. 创建本类对象(就在本类里创建),将对象的应用作为成员变量,并私有静态化
	private static Singleton1 s = new Singleton1();

	// 3. 对外提供获取对象引用的方法getClass()
	public static Singleton1 getS() {
		return s;
	}

}



/*
 * 懒汉式:单例的延迟加载模式
 */
class Singleton2 {
	// 1. 私有构造方法,其他类不能再访问该构造方法了
	private Singleton2() {
	}

	// 2. 创建本类对象的引用(先不着急链接对象)
	private static Singleton2 s ;

	// 3. 对外提供获取对象引用的方法getClass(),如果为引用为空就创建一个,不为空(已经创建过),就返回
	public static Singleton2 getS() {
		if(s == null) {
			//多线程时有隐患,线程1等待,线程2等待,就会创建多个对象
			s = new Singleton2(); 
		}
		return s;
	}

}

/*
 * 第三种单例模式,直接将引用final
 */
class Singleton3 {
	// 1. 私有构造方法,其他类不能再访问该构造方法了
	private Singleton3() {
	}

	// 2. 创建本类对象的引用对象,直接final
	private static final  Singleton3 s = new Singleton3();

}

2、简单工厂模式:

简单工厂模式又叫静态工厂方法模式,定义了一个具体的工厂类负责创建类的对象

  • 优点:客户端不需要再负责对象的创建,从而明确了各个类的指责
  • 缺点:静态工厂类需要负责所有对象的创建,,如果有新的对象增加,或者某些对象的创建方式不同,就需要不断修改工厂类,不利于后期维护

代码演示:
创建一个AnimalFactory工厂类如下
其中Dog和Cat都是抽象类Animal的子类,重写了eat方法

package cn.xinhua;

public class AnimalFactory {

	public Animal createAnimal(String animal) {  // 父类引用指向子类对象
		if ("Dog".equals(animal)) {
			return new Dog();
		} else if ("Cat".equals(animal)) {
			return new Cat();
		} else {
			return null;
		}

	}

}

再来个测试类:

package cn.xinhua;

public class AnimalFactoryTest {

	public static void main(String[] args) {
		AnimalFactory af = new AnimalFactory();
		Dog an = (Dog) af.createAnimal("Dog");
		System.out.println(an);
		an.eat();

	}

}
输出:
cn.xinhua.Dog@70dea4e(还没有重写子类的toString方法,所以打印的是地址值)
狗吃肉

3、工厂模式:
工厂模式算是上面的简单工厂模式的进阶,更容易扩展,但也更复杂了

这里将工厂变为动态的(相比于上面的静态),将工厂类变为实现一个工厂类的接口,重写creatAnimal的方法,这样你每次增加一个动物,都需要实现一个对用的具体的工厂类,然后创建这个动物就用这个动物的工厂类(更加复杂了,但是就像印钱一样,只能国家印,要创建对象只能继承这个工厂类并重写方法)

  • 优点:客户端不需要再负责对象的创建,从而明确了各个类的指责,如果有新的对象增加,只需要增加一个具体的类和具体的工厂即可(从Animal那里继承的子类和从Factory那里实现的工厂),不影响已有代码,后期维护容易,增强了系统的扩展性,感觉就是你要开个厂就需要向国家这个最大的厂报备一样
  • 缺点:代码多代码多代码多

代码演示:

工厂接口:

package cn.xinhua;

public interface Factory {
	public Animal createAniama();

}

Dog类的工厂类(实现了上面的工厂接口):
每次创建一个对象都要相应地创建一个此类的工厂类

package cn.xinhua;

public class DogFactory implements Factory {

	@Override
	public Animal createAniama() {

		return new Dog();
	}

}

再来个测试类:
先创建此类的工厂类对象,然后用这个工厂类对象创建此类的对象(好复杂,有毒!)

package cn.xinhua;

public class AnimalFactoryTest {

	public static void main(String[] args) {
		DogFactory dg = new DogFactory();
		Dog dog = (Dog) dg.createAniama();
		dog.eat();

	}

}
输出:狗吃肉

4、适配器模式:

适配器是实现了监听器接口下面的抽象类,因为我没有看GUI,所以就不用监听器的概念了

定义:

  • 通常接口中有很多个方法,而程序中不一定所有的都用得到,但又必须重写,很繁琐
  • 适配器简化了这些操作,我们定义的类只要继承适配器,然后重写需要的方法即可

原理:

  • 适配器就是一个类,实现了接口,重写了其中的所有的方法,但方法都是空的
  • 适配器类定义成抽象的,因为创建该类的对象,方法都是空的没有意义

代码实例:

package cn.xinhua;

public class AnimalFactoryTest {
//监听器接口,就是有很多方法的接口
	public interface Listen {
		public void method1();

		public void method2();

		public void method3();

		public void method4();
	}
//适配器
	abstract class Middle implements Listen {

		@Override
		public void method1() {
		}

		@Override
		public void method2() {
		}

		@Override
		public void method3() {
		}

		@Override
		public void method4() {
		}

	}
	
//继承适配器的类,不用实现监听器中全部的方法了
	class Men extends Middle {
		public void method1() {
			System.out.println(1);
			System.out.println(2);
			System.out.println(3);

		}
	}

}

5、模板方法设计模式:

具体看:

设计模式之 - 模板模式(Template Pattern)

其实就是分权,国家定义一个大概的方法/模板,不会面面俱到,然后地方上实现具体的做法,有点像类的继承的思想,增加了代码的泛化能力

猜你喜欢

转载自blog.csdn.net/weixin_39782583/article/details/84986963