1、工厂模式
1.1、简单工厂模式
根据条件创建并获取基类的某一个派生类实例。
package com.zy.demo.design;
/**
* 简单工厂模式
* @author zy
*/
public class AnimalFactory {
/**
* 公有静态方法生产派生类实例
* @param name 派生类实例名称
* @return 指定派生类实例
*/
public static Animal getAnimal(String name){
switch (name){
case "cat":
return new Cat();
case "dog":
return new Dog();
default:
return null;
}
}
}
/**
* 基类——动物
*/
interface Animal{
/**
* 动物的进食行为
*/
void eat();
}
/**
* 派生类——狗
*/
class Dog implements Animal{
/**
* 狗的进食行为
*/
@Override
public void eat() {
System.out.println("Dog eats food.");
}
}
/**
* 派生类——猫
*/
class Cat implements Animal{
/**
* 猫的进食行为
*/
@Override
public void eat() {
System.out.println("Cat eats food.");
}
}
1.2、工厂模式
先选择使用的工厂,再选择需要的产品。
package com.zy.demo.design;
/**
* 工厂模式
* @author zy
*/
public class Factory {
//测试
public static void main(String[] args){
CarFactory carFactory = new ChineseCarFactory();
System.out.println(carFactory);
Car car = carFactory.produce("HongQi");
System.out.println(car);
if(car != null){
car.run();
}
}
}
/**
* 汽车工厂基类
*/
interface CarFactory{
/**
* 汽车生产行为
*/
Car produce(String name);
}
/**
* 中国汽车工厂派生类
*/
class ChineseCarFactory implements CarFactory{
/**
* 中国汽车生产行为
*/
@Override
public Car produce(String name) {
if ("HongQi".equals(name)) {
return new HongQi();
}
return null;
}
}
/**
* 美国汽车工厂派生类
*/
class AmericanCarFactory implements CarFactory{
/**
* 美国汽车生产行为
*/
@Override
public Car produce(String name) {
if ("Benz".equals(name)) {
return new Benz();
}
return null;
}
}
/**
* 汽车基类
*/
interface Car{
/**
* 汽车运行
*/
void run();
}
/**
* 奔驰汽车派生类
*/
class Benz implements Car{
@Override
public void run() {
System.out.println("Benz car is running.");
}
}
/**
* 红旗汽车派生类
*/
class HongQi implements Car{
@Override
public void run() {
System.out.println("HongQi car is running.");
}
}
1.3、抽象工厂模式
某一类的产品统一从一个工厂生产。解决工厂模式可能出现的产品不兼容问题,缺点是每增加一种产品,需要在所有工厂类中添加生产的方法。
package com.zy.demo.design;
/**
* 抽象工厂模式
* @author zy
*/
public class AbstractFactory {
public static void main(String[] args){
AbstractComputerFactory acf = new AmdComputerFactory();
System.out.println("ComputerFactory="+acf);
HardDisk hardDisk = acf.makeHardDisk();
System.out.println("HardDisk="+hardDisk);
if(hardDisk != null){
hardDisk.save();
}
Screen screen = acf.makeScreen();
System.out.println("Screen="+screen);
if(screen != null){
screen.show();
}
}
}
/**
* 硬盘抽象产品
*/
interface HardDisk{
/**
* 存储
*/
void save();
}
/**
* 显示器抽象产品
*/
interface Screen{
/**
* 显示
*/
void show();
}
/**
* 电脑抽象工厂
*/
interface AbstractComputerFactory{
/**
* 生产硬盘
* @return 抽象产品硬盘
*/
HardDisk makeHardDisk();
/**
* 生产显示器
* @return 抽象产品显示器
*/
Screen makeScreen();
}
/**
* AMD硬盘
*/
class AmdHardDisk implements HardDisk{
@Override
public void save() {
System.out.println("AMD HardDisk save.");
}
}
/**
* AMD显示器
*/
class AmdScreen implements Screen{
@Override
public void show() {
System.out.println("AMD Screen show.");
}
}
/**
* Intel硬盘
*/
class IntelHardDisk implements HardDisk{
@Override
public void save() {
System.out.println("Intel HardDisk save.");
}
}
/**
* Intel显示器
*/
class IntelScreen implements Screen{
@Override
public void show() {
System.out.println("Intel Screen show.");
}
}
/**
* AMD电脑工厂
*/
class AmdComputerFactory implements AbstractComputerFactory{
@Override
public HardDisk makeHardDisk() {
return new AmdHardDisk();
}
@Override
public Screen makeScreen() {
return new AmdScreen();
}
}
/**
* Intel电脑工厂
*/
class IntelComputerFactory implements AbstractComputerFactory{
@Override
public HardDisk makeHardDisk() {
return new IntelHardDisk();
}
@Override
public Screen makeScreen() {
return new IntelScreen();
}
}
2、单例模式
创建唯一实例的对象。
2.1、内部类模式
public class Singleton {
//声明单例对象
private Singleton singleton;
/**
* 构造函数私有化,禁止通过new创建对象
*/
private Singleton(){
}
/**
* 定义静态内部类
*/
private static class SingletonInstance{
private static Singleton singleton = new Singleton();
}
/**
* 获取单例对象,调用方法时才会创建对象。
* @return 单例对象
*/
public static Singleton getInstance(){
return SingletonInstance.singleton;
}
}
2.2、饿汉模式
public class Singleton {
//静态初始化对象实例
private static Singleton singleton = new Singleton();
/**
* 构造函数私有化,禁止通过new创建对象
*/
private Singleton(){
}
/**
* 获取单例对象
* @return 单例对象
*/
public static Singleton getInstance(){
return singleton;
}
}
2.3、双重检查模式
public class Singleton {
//声明可见静态对象实例,volatile修饰符作用是防止指令重排序
private volatile static Singleton singleton;
/**
* 构造函数私有化,禁止通过new创建对象
*/
private Singleton(){
}
/**
* 获取单例对象
* @return 单例对象
*/
public static Singleton getInstance(){
//先判断对象是否为空
if(singleton == null){
//如果对象为空,则添加类锁
synchronized (Singleton.class){
//指令重排序的情况导致对象先被分配到内存空间但是未初始化,即先读后写,所以需要设置对象内存可见。
if(singleton == null){
//创建对象
singleton = new Singleton();
}
}
}
return singleton;
}
}
3、建造者模式
先将对象的属性赋值给建造者,再由建造者将属性复制给实际产生的对象。适用于属性数量多且有校验规则的场景。
package com.zy.demo.design;
/**
* 建造者模式
* @author zy
*/
public class Builder {
public static void main(String[] args){
User user = new UserBuilder().id(20L).name("zy").age(27).sex('男').build();
System.out.println(user);
}
}
/**
* 用户类
*/
class User{
//编号
private long id;
//姓名
private String name;
//年龄
private int age;
//性别
private char sex;
/**
* 有参构造方法私有化
* @param id 编号
* @param name 姓名
* @param age 年龄
* @param sex 性别
*/
public User(long id, String name, int age, char sex){
this.id = id;
this.name = name;
this.age = age;
this.sex = sex;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
}
/**
* 用户建造者
*/
class UserBuilder{
//编号
private long id;
//姓名
private String name;
//年龄
private int age;
//性别
private char sex;
/**
* 编号赋值建造者
* @param id 编号
* @return 建造者
*/
public UserBuilder id(long id){
this.id = id;
return this;
}
/**
* 姓名赋值建造者
* @param name 姓名
* @return 建造者
*/
public UserBuilder name(String name){
this.name = name;
return this;
}
/**
* 年龄赋值建造者
* @param age 年龄
* @return 建造者
*/
public UserBuilder age(int age){
this.age = age;
return this;
}
/**
* 性别赋值建造者
* @param sex 性别
* @return 建造者
*/
public UserBuilder sex(char sex){
this.sex = sex;
return this;
}
/**
* 创建对象并增加校验规则
* @return 对象实例
*/
public User build(){
if(this.id > 10000L){
throw new IllegalArgumentException("属性id不能大于10000");
}
if(this.name == null){
throw new IllegalArgumentException("属性name不能为空");
}
if(this.age < 20 || this.age > 60){
throw new IllegalArgumentException("属性age取值范围为20到60");
}
return new User(this.id,this.name,this.age,this.sex);
}
}