六大原则*
1、单一职责原则:指的是应该有且仅有一个原因引起类的变更。
2、里氏替换原则:所有引用基类的地方必须能透明地使用其子类的对象,通俗的来讲就是父类能出现的地方子类就可以出现,但是反过来就不行了。子类可以扩展父类的功能,但不能改变父类原有的功能,里氏替换原则为良好的继承定义了一个规范。
3、依赖倒置原则:高层模块不应该依赖低层模块、抽象不应该依赖细节,细节依赖抽象,在Java中的表现为面向接口编程 OOP。
4、接口隔离原则:客户端不应该依赖它不需要的接口;类间的依赖关系应该建立在最小的接口上;根据接口隔离原则拆分接口时,首先必须满足单一职责原则。
5、迪米特法则:一个对象应该对其他对象有最少的了解,一个类只需要知道自己需要耦合或者调用类的public方法即可。
6、开闭原则:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。
一、Spring 框架中用到了的设计模式
1、代理模式—在AOP和remoting中被用的比较多。
2、单例模式—在spring配置文件中定义的bean默认为单例模式。
3、模板方法—用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。
4、前端控制器—Spring提供了DispatcherServlet来对请求进行分发。
5、视图帮助(View Helper )—Spring提供了一系列的JSP标签,高效宏来辅助将分散的代码整合在视图里。
6、依赖注入—贯穿于BeanFactory / ApplicationContext接口的核心理念。
7、工厂模式—BeanFactory用来创建对象的实例。
二、微服务架构的六种常用设计模式
1、代理设计模式
2、聚合设计模式
3、链条设计模式
4、聚合链条设计模式
5、数据共享设计模式
6、异步消息设计模式
三、java中,抽象类与接口之间有什么区别
1.一个类可以实现多个接口 ,但却只能继承最多一个抽象类。
2.抽象类可以包含具体的方法 , 接口的所有方法都是抽象的。
3.抽象类可以声明和使用字段 ,接口则不能,但接口可以创建静态的final常量。
4.接口的方法都是public的,抽象类的方法可以是public,protected,private或者默认的package。
5.抽象类可以定义构造函数,接口却不能。
四、JDK库使用的设计模式
1、装饰器设计模式(Decorator design pattern)被用于多个Java IO类中。
2、单例模式(Singleton pattern)用于Runtime,Calendar和其他的一些类中。
3、工厂模式(Factory pattern)被用于各种不可变的类如Boolean,像Boolean.valueOf,观察者模式(Observer pattern)被用于Swing和很多的事件监听中。
五、单例设计模式的好处
1、某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销。
2、省去了new操作符,降低了系统内存的使用频率,减轻GC压力。
3、有些类如交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了。(比如一个军队出现了多个司令员同时指挥,肯定会乱成一团),所以只有使用单例模式,才能保证核心交易服务器独立控制整个流程。
六、实现线程安全的单例模式
public class MailListReader {
private static MailListReader reader = null;
private MailListReader(){}//构造函数私有
public static MailListReader getInstance() {
if(singleton == null){
synchronized (Singleton.class){
if(singleton == null){
singleton = new Singleton();
}
}
}
}
}
七、详解工厂模式
简单工厂模式:想象一下,一个蛋糕机,有的人想吃香蕉味,有人想吃苹果味的,那么可以做一种可以生成各种口味的蛋糕机,这种蛋糕机就是简单工厂模式。
代码实现:
1、 首先定义一个蛋糕接口,里边有一个方法,就是生产蛋糕
public interface Cake {
public void production();
}
2、定义两个类,AppleCake、BananaCake,并实现Cake接口,实现其中的方法,生产自己独特的口味的蛋糕
public class AppleCake implements Cake {
public void production(){
System.out.println("生产苹果味的蛋糕");
}
}
public class BananaCake implements Cake {
public void production() {
System.out.println("生产香蕉味的蛋糕");
}
}
3、定义一个蛋糕工厂类,制作不同口味的蛋糕
public class CakeFactory {
public static Cake creamCake(String type){
Cake cake = null;
switch(type){
case "Apple":
cake = new AppleCake();
break;
case "Banana":
cake = new BananaCake();
break;
default:
break;
}
return cake;
}
}
4、客户端实现生产自己需要的蛋糕口味
// 通过统一的蛋糕生产工厂,传入不同参数生产不同口味的蛋糕
public class CakeClient {
public static void main(String[] args) {
Cake appleCake = CakeFactory.creamCake("Apple");
appleCake.production();
Cake bananaCake = CakeFactory.creamCake("Banana");
bananaCake.production();
}
}
小结:简单工厂模式违背了开闭原则,扩展性差。
工厂方法模式:
对比上面的简单工厂模式的业务,就是定义一个工厂接口,然后实现一个个生产不同口味的工厂,然后客户端就调用这些不同的工厂实现不同的口味。
代码实现:
1、 首先定义一个蛋糕接口,里边有一个方法,就是生产蛋糕,然后分别定义AppleCake、BananaCake去实现这个接口,此处省略。
public interface Cake {
public void production();
}
2、定义工厂接口
public interface CakeFactory {
public Cake createCake();
}
3、分别定义AppleCakeFactory、BananaCakeFactory实现刚刚定义的接口
public class AppleCakeFactory implements CakeFactory {
public Cake createCake() {
return new AppleIceCake();
}
}
public class BananaCakeFactory implements CakeFactory {
public Cake createIceCake() {
return new BananaCake();
}
}
4、 客户端代码
public class CakeClient {
public static void main(String[] args) {
//生产苹果味蛋糕
CakeFactory appleFactory = new AppleCakeFactory();
Cake appleIceCake = appleFactory.createIceCake();
appleIceCake.production();
//生产香蕉口味蛋糕
CakeFactory bananaFactory = new BananaCakeFactory();
Cake bananaIceCake = bananaFactory.createIceCake();
bananaIceCake.production();
}
}
小结: 每个工厂只生产一种产品,客户端通过不同的工厂去生产不同的产品,而生产哪一产品的逻辑交给客户端这边去处理就OK了。
抽象工厂模式:存在多个抽象产品类,每个抽象产品类可以派生出多个具体产品类,工厂提供多种方法,去生产各种类型产品,此处省略代码。
总结:简单工厂模式适用于工厂类需要创建的对象比较少的情况,客户只需要传入具体的参数,就可以忽略工厂的生产细节,去获取想要的对象;工厂方法模式,主要是针对单一产品结构的情景;抽象工厂模式则是针对多级产品结构(系列产品)的一种工厂模式。