单一职责原则
开闭原则
里氏替换原则
依赖注入原则
接口分离原则
迪米特原则
Singleton.java
package demo1;
/*
* 单例设计模式的演示
*
* 单例模式的特点:
* 1.单例类只能有一个实例
* 2.单例类必须自己创建自己的唯一实例
* 3.单例类必须给所有其他对象提供这一实例
*/
public class Singleton {
/*-----------------------------创建Singleton实例------------------------------------*/
// 饿汉式,因为很饿,所以直接创建实例,然后公共方法返回本对象
private static Singleton singleton = new Singleton();
// 私有化构造,防止其他类能够自己创建实例
private Singleton(){
}
// 给外界提供公共方法来创建对象
public static Singleton getInstance(){
return singleton;
}
}
TestSingleto.java
package demo1;
public class TestSingleTon {
public static void main(String[] args) {
/*-----------------------------创建Singleton实例------------------------------------*/
// Singleton singleton1 = new Singleton();
// Singleton singleton2 = new Singleton();
// Singleton singleton3 = new Singleton();
// 调用方法创建实例,虽然调用了三次方法,但是创建的对象却是同一个
Singleton singleton1 = Singleton.getInstance();
Singleton singleton2 = Singleton.getInstance();
Singleton singleton3 = Singleton.getInstance();
System.out.println(singleton1);
System.out.println(singleton2);
System.out.println(singleton3);
}
}
Singleton.java
/*
* 懒汉式:可能会发生线程安全问题,因为可能在getInstance方法之中创建了多个线程
*/
public class Singleton{
private static Singleton singleton = null;
//私有化构造,防止其他类能够自己创建实例
private Singleton(){
}
//给外界提供公共方法来创建对象,为了防止线程安全问题,添加关键字synchronized
//怎样的线程安全问题?在一个线程进入下面方法时没有创建实例执行了if语句,另一个线程同时进入显示没有实例继续if语句创建实例
public static synchronized Singleton getInstance(){
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
TestSingleto.java
package demo1;
public class TestSingleTon {
public static void main(String[] args) {
/*-----------------------------创建Singleton实例------------------------------------*/
// Singleton singleton1 = new Singleton();
// Singleton singleton2 = new Singleton();
// Singleton singleton3 = new Singleton();
// 调用方法创建实例,虽然调用了三次方法,但是创建的对象却是同一个
Singleton singleton1 = Singleton.getInstance();
Singleton singleton2 = Singleton.getInstance();
Singleton singleton3 = Singleton.getInstance();
System.out.println(singleton1);
System.out.println(singleton2);
System.out.println(singleton3);
}
}
Singleton.java
public class Singleton{
private static Singleton singleton = null;
//私有化构造,防止其他类能够自己创建实例
private Singleton(){
}
//给外界提供公共方法来创建对象,为了防止线程安全问题,添加关键字synchronized
//怎样的线程安全问题?在一个线程进入下面方法时没有创建实例执行了if语句,另一个线程同时进入显示没有实例继续if语句创建实例
public static synchronized Singleton getInstance(){
if (singleton == null) {
synchronized(Singleton.class){
if(singleton == null){
singleton = new Singleton();
}
}
}
return singleton;
}
}
TestSingleton.java
package demo1;
public class TestSingleTon {
public static void main(String[] args) {
/*-----------------------------创建Singleton实例------------------------------------*/
// Singleton singleton1 = new Singleton();
// Singleton singleton2 = new Singleton();
// Singleton singleton3 = new Singleton();
// 调用方法创建实例,虽然调用了三次方法,但是创建的对象却是同一个
Singleton singleton1 = Singleton.getInstance();
Singleton singleton2 = Singleton.getInstance();
Singleton singleton3 = Singleton.getInstance();
System.out.println(singleton1);
System.out.println(singleton2);
System.out.println(singleton3);
}
}
ICloneable.java
package demo2;
public class ICloneable {
private String name;//姓名
private int age;//年龄
private String last;//上一家公司
private String address;//公司地址
private Number number;//电话
/*个人信息*/
public void setInfo(String name,int age,Number number){
this.name = name;
this.age = age;
this.number=number;
}
/*工作经验*/
public void setWeek(String last,String address){this.last = last; this.address = address;}
/*查看简历*/
public void show(){
System.out.println("姓名:"+name+",年龄:"+age+",联系电话:"+number.getPhone());
System.out.println("公司名称:"+last+",公司地址:"+address);
}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public int getAge() {return age;}
public void setAge(int age) {this.age = age;}
public String getLast() {return last;}
public void setLast(String last) {this.last = last;}
public String getAddress() {return address;}
public void setAddress(String address) {this.address = address;}
public Number getNumber() {return number;}
public void setNumber(Number number) {this.number = number;}
@Override
public String toString() {
return "ICloneable [address=" + address + ", age=" + age + ", last="
+ last + ", name=" + name + ", number=" + number + "]";
}
}
Number.java
package demo2;
public class Number {
private String phone;
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
TestCloneable.java
package demo2;
/*
* 下面的代码只是简单的复制,不是克隆,因为一个改变,全部改变
*/
public class TestICloneable {
public static void main(String[] args) {
// 创建原型简历模板
ICloneable clone = new ICloneable();
// 设置手机号
Number number = new Number();
number.setPhone("1234567889");
// 设置个人信息
clone.setInfo("张三",17,number);
// 设置工作经验
clone.setWeek("京东","东京");
clone.show();
// 复制简历
System.out.println("-----------------克隆一号----------------------");
ICloneable clone2 = clone;
Number number2 = new Number();
number.setPhone("111111111");
clone2.setInfo("李四", 12, number2);
clone2.show();
System.out.println("-----------------克隆二号----------------------");
ICloneable clone3 = clone;
clone3.show();
}
}
在ICloneable.java中继承接口Cloneable,并重写clone方法
ublic class ICloneable implements Cloneable{
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
将TestCloneable.java中的克隆语句修改如下
System.out.println("-----------------克隆一号----------------------");
ICloneable clone2 = (ICloneable) clone.clone();
Number number2 = clone2.getNumber();
number2.setPhone("123123");
clone2.setInfo("李四", 12, number2);
clone2.show();
System.out.println("-----------------克隆二号----------------------");
ICloneable clone3 = (ICloneable) clone.clone();
clone3.show();
运行结果如下
姓名:张三,年龄:17,联系电话:1234567889
公司名称:京东,公司地址:东京
-----------------克隆一号----------------------
姓名:李四,年龄:12,联系电话:1234567889
公司名称:京东,公司地址:东京
-----------------克隆二号----------------------
姓名:张三,年龄:17,联系电话:1234567889
公司名称:京东,公司地址:东京
克隆分为深克隆和浅克隆,上述是浅克隆,所以电话号码不变
ICloneable.java添加下面代码,并且开头继承序列化
/*
* 深克隆:将对象重新组装,组成新的对象
*
* 利用序列化将对象组装成序列,再将序列转换成对象
*
* 将一个对象复制后,基本数据类型和引用类型重新创建
*/
public Object deepClone() throws Exception{
ByteArrayOutputStream bos = new ByteArrayOutputStream();//声明一个临时空间
ObjectOutputStream ooStream = new ObjectOutputStream(bos);
ooStream.writeObject(this);//将当前对象序列化
byte[] bs = bos.toByteArray();//构件字节数组
ByteArrayInputStream bisArrayInputStream = new ByteArrayInputStream(bs);//反序列化
ObjectInputStream ois = new ObjectInputStream(bisArrayInputStream);//将从bisArrayInputStream读取的数据注入到ois之中
return ois.readObject();//读取数据返回Object类型
}
/*
* java.io.NotSerializableException: demo2.ICloneable,则需要添加序列化关键字Serializable
*/
public class ICloneable implements Cloneable,Serializable{
private static final long serialVersionUID = 2269323637457452994L;
Number.java继续序列化
public class Number implements Serializable{
private static final long serialVersionUID = 1L;//生成序列化版本ID
TestICloneable.java中复制简历部分改成如下
出现未知错误,导致运行结果不理想,具体看Java视频部分
复制简历
System.out.println("-----------------克隆一号----------------------");
ICloneable clone2 = (ICloneable) clone.deepClone();
Number number2 = clone2.getNumber();
number2.setPhone("111111111");
clone2.setInfo("李四", 12, number2);
clone2.show();
System.out.println("-----------------克隆二号----------------------");
ICloneable clone3 = (ICloneable) clone.deepClone();
Number number3 = clone3.getNumber();
number2.setPhone("2222222");
clone2.setInfo("小红", 11, number3);
clone3.setWeek("百度", "北京西二旗");
clone3.show();
简单工厂
一个抽象产品类可以派生出多个具体产品类。一个抽象工厂类可以创建多个具体产品类;
工厂方法
一个抽象产品类可以派生多个具体产品类,一个抽象工厂类可以派生多个具体工厂类,每个具体工厂只能创建一个具体产品类实例;
抽象工厂
多个抽象产品类,每个抽象产品类能派生多个具体产品类,一个抽象工厂类可以派生多个具体工厂类,每个具体工厂类可以创建多个具体
产品类的实例;
优点:客户端不需要负责对象的创建,从而明确了各个类的职责
缺点:如果有新的对象添加,那么就要修改工厂类,不利于后期的维护
package demo3;
/*
* 具体产品类
*/
public class Cat implements Animal{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
package demo3;
/*
* 具体产品类
*/
public class Dog implements Animal{
@Override
public void eat() {
System.out.println("狗吃骨头");
}
}
package demo3;
/*
* 抽象产品类
*/
public interface Animal {
public void eat();
}
package demo3;
/*
* 主要负责创建多个具体的产品类
*/
public class AnimalFactory {
// //生产狗对象
// public static Dog getDog(){
// return new Dog();
// }
//
// //生产猫对象
// public static Cat getCat(){
// return new Cat();
// }
public static Animal getAnimal(String name){
if("dog".equals(name)){
return new Dog();
}else if ("cat".equals(name)) {
return new Cat();
}else {
return null;
}
}
}
package demo3;
public class TestFctory {
public static void main(String[] args) {
/* Dog dog = AnimalFactory.getDog();
dog.eat();
Cat cat = AnimalFactory.getCat();
cat.eat();
Dog dog2 = AnimalFactory.getDog();
System.out.println(dog2);
System.out.println(dog);
System.out.println(cat);
*/
Animal animal = AnimalFactory.getAnimal("dog");
animal.eat();
Animal animal2 = AnimalFactory.getAnimal("cat");
animal2.eat();
}
}
public interface Animal {public void eat();}/*抽象类*/
Factory.java
/*抽象工厂类*/
public interface Factory {
public Animal createAnimal();
}
Dog.java
public class Dog implements Animal{
@Override
public void eat() {System.out.println("狗吃骨头");}
}
Cat.java
public class Cat implements Animal{
@Override
public void eat() {System.out.println("猫吃鱼");}
}
DogFactory.java
public class DogFactory implements Factory{
@Override
public Animal createAnimal() {
return new Dog();
}
}
CatFactory.java
public class CatFactory implements Factory{
@Override
public Animal createAnimal() {
return new Cat();
}
}
TestFactory.java
public class TestFactory {
public static void main(String[] args) {
Factory factory = new DogFactory();
Animal dog = factory.createAnimal();
dog.eat();
Factory factory2 = new CatFactory();
Animal cat = factory2.createAnimal();
cat.eat();
}
}
多个抽象产品类,每个抽象产品类能派生多个具体产品类;
一个抽象工厂类可以派生多个具体工厂类,每个具体工厂类可以创建多个具体产品类的实例;
抽象产品类:水果、蔬菜 → → → 具体产品类:北方水果、南方水果、北方蔬菜、南方蔬菜
抽象工厂类:产品工厂 → → → 具体工厂:北方产品工厂、南方产品工厂
package demo5;
//水果抽象接口
public interface Fruit {
public void fruitInfo();
}
---------------------------------------------------------------------------------------------------------
//蔬菜抽象接口
public interface Vegetable {
public void vegetableInfo();
}
---------------------------------------------------------------------------------------------------------
//具体类:北方水果
public class NorthFruit implements Fruit {
@Override
public void fruitInfo() {
System.out.println("北方苹果");
}
}
---------------------------------------------------------------------------------------------------------
public class SouthFruit implements Fruit{
@Override
public void fruitInfo() {
System.out.println("南方香蕉");
}
}
---------------------------------------------------------------------------------------------------------
//具体类:北方蔬菜
public class NorthVegetable implements Vegetable{
@Override
public void vegetableInfo() {
System.out.println("北方西红柿");
}
}
---------------------------------------------------------------------------------------------------------
//具体类:南方蔬菜
public class SouthVegetable implements Vegetable{
@Override
public void vegetableInfo() {
System.out.println("南方土豆");
}
}
下述几个工厂文件,抽象工厂类派生具体工厂类,具体工厂类创建具体蔬菜水果类
//工厂抽象接口
public interface Factory {
Fruit createFruit();
Vegetable createVegetable();
}
---------------------------------------------------------------------------------------------------------
//具体类:南方产品工厂
public class SouthProduuctFactory implements Factory{
@Override
public Fruit createFruit() {
return new SouthFruit();
}
@Override
public Vegetable createVegetable() {
return new SouthVegetable();
}
}
---------------------------------------------------------------------------------------------------------
public class NorthProductFactory implements Factory{
@Override
public Fruit createFruit() {
return new NorthFruit();
}
@Override
public Vegetable createVegetable() {
return new NorthVegetable();
}
}
public interface UserDao {
public void delete();
}
---------------------------------------------------------------------------------------------------------
public class UserDaoImpl implements UserDao {
@Override
public void delete() {
//如果想在删除数据的前面添加一些东西,删除数据的后面添加一些东西,但是由不想修改别人的代码,则使用代理类
System.out.println("删除数据");
}
}
---------------------------------------------------------------------------------------------------------
public class UserProxy implements UserDao {
private UserDao dao;
//通过构造方式接收代理对象
public UserProxy(UserDao dao){
this.dao=dao;
}
//在代理对象的前面、后面添加一些内容
@Override
public void delete() {
System.out.println("开启事务");
dao.delete();
System.out.println("提交事务");
}
}
---------------------------------------------------------------------------------------------------------
public class TestProxy {
public static void main(String[] args) {
UserDao dao = new UserDaoImpl();
dao.delete();
UserDao proxy = new UserProxy(dao);
proxy.delete();
}
}
public interface UserDao {
public void delete();
public void save();
}
---------------------------------------------------------------------------------------------------------
public class UserDaoImpl implements UserDao {
@Override
public void delete() {
System.out.println("删除数据");
}
@Override
public void save() {
System.out.println("添加数据 ");
}
}
---------------------------------------------------------------------------------------------------------
/*
* JDK动态代理
* jdk中生成代理对象的API
* 代理类所在的包:java.lang.reflect.Proxy
* JDK实现代理只需要使用newProxyInstance方法,但是该方法需要接收三个数据
* loader - 指定当前目标对象使用类加载器
* interfaces - 目标对象实现的接口的类型,使用泛型方式确认类型
* h - 事件处理,执行目标对象的方法时,会触发事件处理器的方法,会把当前执行目标对象的方法作为参数传入
*/
public class UserProxy {
private Object object;
public UserProxy(Object object){
this.object=object;
}
public Object getProxyObject(){
//接下来调用的是Java中的一个API
//getClassLoader()是反射中的类加载器
//获取类实现的一个接口object.getClass().getInterfaces()
//事件方法,是一个接口,传入一个接口,所以需要用内部类的一种方式来实现
return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), new InvocationHandler() {
@Override/*下面参数中,动态调用哪些方法,method就是谁*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("开启事务");
Object invoke = method.invoke(object, args);//这里是原本的内容,上下为要添加的内容
System.out.println("提交事务");
return invoke;
}
});
}
}
---------------------------------------------------------------------------------------------------------
public class TestProxy {
public static void main(String[] args) {
UserDao dao = new UserDaoImpl();
UserProxy up = new UserProxy(dao);
UserDao proxyObject = (UserDao) up.getProxyObject();
proxyObject.delete();
proxyObject.save();
}
}
引入Spring的jar包,在项目中新建一个lib文件夹,将Spring的jar包Copy进去,然后右键那个文件,再点击Build Path
再点击Add to Build Path
public class UserDao {
public void save() {
System.out.println("保存数据");
}
}
---------------------------------------------------------------------------------------------------------
/*
* Cglib子类代理工厂
* 对UserDao在内存中动态构件一个子类对象
*/
public class CglibProxyFactory implements MethodInterceptor{//要实现Cglib必须继承一个接口
private Object target;
public CglibProxyFactory(Object target){
this.target = target;
}
//给目标对象创建一个代理
public Object getProxyInstance(){
//1.工具类
Enhancer en = new Enhancer();
//2.设置父类
en.setSuperclass(target.getClass());
//3.设置回调函数
en.setCallback(this);
//4.创建子类(代理对象)
return en.create();
}
@Override
public Object intercept(Object arg0,Method arg1,Object[] arg2,MethodProxy arg3) throw Throwable{
System.out.println("开启事务");
//执行目标对象的方法
Object invokeObject = Method.invoke(target,arg2);
System.out.println("提交事务");
return null;
}
}
---------------------------------------------------------------------------------------------------------
public class TestCglib {
public static void main(String[] args) {
//目标对象
UserDao dao = newUserDao();
//代理对象
CglibProxyFactory c = new CglibProxyFactory(dao);
UserDao d = (UserDao) c.getProxyInstance();
//执行代理对象的方法
d.save();
}
}