设计模式6个原则?
1.开放闭合原则:对“扩展”开放,对“修改”闭合;在我们设计一个类的时候,尽量去预留他的功能的接口,多扩展,少修改;
2.单一职责原则:让一个类的功能尽量的不要那么复杂,当一个职责(功能)需要改变时,防止“耦合”太强,影响到其他的功能;
3.依赖倒转原则:抽象不应该依赖细节,细节应该依赖抽象;多对接口编程,必要直接去针对一个具体的类编程,让类去实现接口;
4.里氏替换原则:子类可以替换掉父类;即任何一个子类都属于父类,都能被父类引用所指向。
5.迪米特法则:最少知道原则,强调一个类不要过于依赖另一个类,不需要公开的方法属性就用private修饰,减少类之间的“”耦合。
6.接口隔离原则:让接口的功能细化,用多个接口,让每一个接口去定义一种功能,而不是让一个接口具有多个功能;
总体思想:低耦合,高内聚;多用接口少用类,让类去实现接口;让功能细化,让一个类负责一种功能;
常用的几种设计模式原理及实现?
1. 单例模式(6种):
(1)单线程,定义一个private static 实例,将构造函数修饰为private,再定义一个getInstance方法返回这个实例即可;
public class Singleton {
private static Singleton instance;
private Singleton() {
//private Constructor
}
public Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
(2)多线程,懒汉模式,对getInstance()方法加synchronized 修饰,太笨重,每次调用都会阻塞;
public class Singleton {
private static Singleton instance;
private Singleton() {
//private Constructor
}
public synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
(3)双重加锁判断非空,上一版的改进版,如果为空再加锁,多一个非空判断;
public class Singleton {
private static Singleton instance;
private Singleton() {
//private Constructor
}
public Singleton getInstance() {
if (instance == null) {//第一次判断:是否需要加锁
synchronized (Singleton.class) {
if (instance == null) {//第二次判断:是否需要实例化
instance = new Singleton();
}
}
}
return instance;
}
}
(4)饿汉模式,直接在声明private static时就将对象实例化出来;缺点:没有做到lazy loading;
public class Singleton {
private static Singleton instance = new Singleton(); //在这里就已经完成实例化
private Singleton() {
//private Constructor
}
public Singleton getInstance() {
return instance;
}
}
(5)静态内部类实现,上一版本的改进版,也是推荐的一种;
public class Singleton {
private Singleton() {
//private Constructor
}
static class SingletonInner {
private static Singleton instance = new Singleton();
}
public Singleton getInstance() {
return SingletonInner.instance;
}
}
(6)枚举,Enumeration天然的实现了“单例模式”(如果只有一个实例的话);
运用场景:只需要一个公用对象来保存某种状态,例如数据库连接对象Connection,只需要一个实例;“空对象”都是单例;
2. 简单工厂模式
工厂模式就是为了获得某个具体的产品类的实例;
几种工厂模式其实都差不多,区别在于工厂类是一个还是多个,根据什么返回实例(具体类名String返回对应类的实例),这个用于区别简单工厂和工厂方法;产品之间有无继承关系,存在多个产品接口,构成“产品簇”,这个用于区分抽象工厂;
工厂模式主要包括:产品接口;工厂接口;产品实现类(多个);工厂实现类(一个或多个)工厂设计模式框架:
interface Product {//产品接口
void doA();
void doB();
void doC();
}
interface Factory {//工厂接口
Product getProduct();
}
class ProductA implements Product {//产品实现类A
public void doA() {
System.out.println("A—doA");
}
public void doB() {
System.out.println("A—doB");
}
public void doC() {
System.out.println("A—doC");
}
}
class ProductB implements Product {//产品实现类B
public void doA() {
System.out.println("B—doA");
}
public void doB() {
System.out.println("B—doB");
}
public void doC() {
System.out.println("B—doC");
}
}
class FactoryImp implements Factory {//工厂实现类
private Product p;
public Product getProduct() {
//p = new ...() ...具体返回哪个实例...
return p;
}
}
简单工厂:一个工厂实现类
class FactoryImp implements Factory {//简单工厂实现类
private Product p;
public Product getProduct(String name) {
switch (name) {
case "ProductA":
p = new ProductA();
;
break;
case "ProductB":
p = new ProductB();
break;
}
return p;
}
}
工厂方法模式:每个产品一个工厂
class FactoryImpA implements Factory {//工厂实现类
public Product getProduct() {
return new ProductA();
}
}
class FactoryImpB implements Factory {//工厂实现类
public Product getProduct(String name) {
return new ProductA();
}
}
抽象工厂模式:产品接口之间形成了“产品簇”
interface Product {//产品接口A
void doA();
void doB();
void doC();
}
interface Toy {//产品接口B
void doD();
void doE();
void doF();
}
interface Factory {
Product getProduct();
Toy getToy();
}
5.策略设计模式
利用了“多态”/里氏替换原则;
一个父类接口;几个子类实现接口的抽象方法;一个配置类,调用接口的实现类的方法;
interface Strategy {//父类接口
void doSth();//抽象方法
}
class StrategyA implements Strategy {//子类A
public void doSth() {
System.out.println("doA");
}
}
class StrategyB implements Strategy {//子类B
public void doSth() {
System.out.println("doB");
}
}
class StrategyC implements Strategy {//子类C
public void doSth() {
System.out.println("doC");
}
}
public class Context {//配置类
public void doStrategy(Strategy s) {
s.doSth();//根据实际传入的子类,调用相应的方法
}
}
6.模板方法模式
主要是用到了抽象类(而不是接口),一部分公用方法要让子类继承(这类方法称之为模板方法),另一部分让子类自己实现;
一个抽象模板类;几个子类;
public abstract class Model {//抽象模板类
public void doA() {//公用方法A
System.out.println("doA");
}
public abstract void doB();//抽象方法B
public abstract void doC();//抽象方法C
public void doD() {//公用方法D
System.out.println("doD");
}
public boolean hook() {//“钩子”方法,可以被子类覆盖,来控制执行process逻辑;
return true;
}
public void processModel() {//执行process逻辑——模板方法
doA();
if (hook()) {//hock()决定了执行逻辑,子类覆盖该方法,反转执行B、C的逻辑
doB();
} else {
doC();
}
doD();
}
}
7.组合设计模式
类似“树”结构,来表示“部分—整体”的关系;每个子类都是一个树的结点,只不过分为树叶结点和树枝结点;
一个结点抽象类;许多树叶结点类和树枝结点类;
public abstract class Component {//结点抽象类
String name;
public Component(String name) {
this.name = name;
}
public abstract void add(Component c);//添加子节点
public abstract void remove(Component c);//删除子节点
public abstract void display(int depth);//根据“深度”,打印 树结构
}
class Leaves extends Component {//叶子节点
public Leaves(String name) {
super(name);
}
public void add(Component c) {
//方法为空
}
public void remove(Component c) {
//方法为空
}
public void display(int depth) {
System.out.println("Leave-" + depth + "-" +[this.name] (http://this.name/));//打印name
}
}
class Composite extends Component {//树枝结点
private List<Component> children = new ArrayList<Component>();//子节点列表
public Composite(String name) {
super(name);
}
public void add(Component c) {
children.add(c);
}
public void remove(Component c) {
children.remove(c);
}
public void display(int depth) {
System.out.println("Composite-" + depth + "-" +[this.name] (http://this.name/));
for (Component c : children) {
c.display(depth + 1);//打印子节点深度,拓扑图
}
}
}
8.装饰设计模式
有点像“代理模式”,装饰者父类实现了装饰接口,并拥有一个装饰接口的实例;装饰者类则继承了装饰者父类,并覆盖了装饰者父类的方法(实际上是扩展了方法,再调用装饰者父类的方法);装饰者类之间可以嵌套使用;
interface Component {//装饰接口
void operation();
}
class Decorator implements Component {//装饰者父类
private Component c;//私有对象
public void setComponent(Component c) {//传入一个装饰类对象
this.c = c;
}
public void operation() {
if (c != null) {
c.operation();//调用的是c的operation();
}
}
}
class DecoratorA extends Decorator {//装饰者子类A
private void methodA() {
System.out.println("doA");//DecoratorA自身的方法
}
public void operation() {//这一步则实现了“装饰”/扩展 功能
methodA();
super.operation();
}
}
class DecoratorB extends Decorator {
private void methodB() {
System.out.println("doB");//DecoratorB自身的方法
}
public void operation() {//这一步则实现了“装饰”/扩展 功能
methodB();
super.operation();
}
}
9.适配器模式
适配器就是转接线,把两个不通用的接口通过适配器让他们可以通用;即一个方法需要A类参数,但这个方法内部是用B类的方法实现的,B类的对象传不进去,则需要一个适配器来转换,将B类对象封装到一个A类(子类)里面;
public class Test {//测试类
public static void main(String[] args) {
new Context().doSth(new Adaptor(new B()));
}
}
class Context {//当前类
void doSth(A a) {
a.request();//这里需要B类的operation()方法,但无法传入B类实例
}
}
class A {//类A
void request() {
System.out.println("A-doSth");
}
}
class B {
void operation() {
System.out.println("B-doSth");
}
}
class Adaptor extends A {//适配器类
private B b;
public Adaptor(B b) {
this.b = b;
}
@Override
void request() {//覆盖A类方法
b.operation();
}
}
10.代理模式(动态代理)
代理模式有点像“装饰者模式”,即代理类拥有一个真实对象类的实例,通过代理类对象,调用真实对象的方法,可以扩展真实类对象的方法,也可以拦截对真实类方法的调用;即拦截了对真实对象的直接访问;
class Person {//真实类
void doA() {
System.out.println("doA");
}
void doB() {
System.out.println("doB");
}
void doC() {
System.out.println("doC");
}
}
class Proxy {//代理类
private Person p;
public Proxy(Person p) {
this.p = p;
}
void doA() {
System.out.println("A");//扩展doA()功能
p.doA();
}
void doB() {
p.doB();
}
void doC() {
System.out.println("defence doC()");//拦截doC()功能
//p.doC();
}
}
11.观察者模式(发布-订阅模式)
包括一个被观察者(发布者)类和多个观察者类(订阅者);当“状态”发生改变,被观察者通知所有与它绑定的观察者,告诉他们当前的状态,并作出相应的反应;
interface Subject {//被观察者接口
void addObserver(Observer o);//绑定观察者
void removeObserver(Observer o);//解绑
void setState(String s);//设置状态
String getState();//返回状态值
void notifyObserver();//通知所有观察者
}
interface Observer {//观察者接口
void update();//观察者做出反应
void setSubject(Subject s);//绑定一个被观察者
}
class SubjectA implements Subject {
private List<Observer> myObserver = new ArrayList<Observer>();//绑定的观察者列表
private String state;//状态
public void addObserver(Observer o) {
myObserver.add(o);
}
public void removeObserver(Observer o) {
myObserver.remove(o);
}
public void setState(String s) {
this.state = s;
}
public String getState() {
return this.state;
}
public void notifyObserver() {
for (Observer o : myObserver) {
o.update();//所有的观察者作出反应
}
}
}
class ObserverA implements Observer {
private Subject s;
public void setSubject(Subject s) {
this.s = s;
}
public void update() {
System.out.println(s.getState());//获取最新状态值
System.out.println("do some ReactionA.");//做出反应
}
}