Java常用的设计原则和设计模式

Java常用的设计原则和设计模式

1.常用的设计原则

1.1软件开发的流程

  • 需求分析文档,概要设计文档,编码和测试,安装和调试,维护和升级

1.2常用的设计原则

  • 开闭原则

对扩展开放,对修改关闭

若需在类中添加成员变量或成员方法时,新建一个类继承该类,不能在原代码中修改

  • 里氏代换原则

任何基类可以出现的地方,子类一定可以出现

尽量使用多态,适用于多个子类所调用的方法相同

//父类,形状
public class Shape{ public void show(); }
//子类,矩形,圆形
public class Rectangle extends Shape{ public void show(); }
public class Circle extends Shape{ public void show(); }
//测试类
public class ShapeTest{
    //自定义成员方法实现将参数指定的矩形对象打印出来
    public static void draw(Rectangele r){
        r.show();
    }
    //自定义成员方法实现将参数指定的圆形对象打印出来
    publi static void draw (Circle c){
        c.show();
    }
    //多态实现打印任意Shape子类的对象
    Shape s1 = new Rectangle();
    Shape s2 = new Circle();
    public static void draw(Shape s){
        s.show();
    }
}
  • 依赖倒转原则

尽量多依赖于抽象类或接口而不是具体实现类,对子类有强制性和规范性

  • 接口隔离原则

尽量使用小接口而不是大接口,降低类之间的耦合度

//例如创建一个Animal接口,需要包含run()和fly()方法
public interface Animal{
    void run();
    void fly();
}
//新建一个Dog类继承接口,则需要重写run方法和fly方法,显然不合理。所以这里使用小接口RunAnimal和FlyAnimal
public interface RunAnimal{ void run(); }
public class Dog implements RunAnimal{
    @Override
    public void run(){}
}
  • 迪米特法则(最少知道原则)

一个实体应当尽量少与其他实体之间发生相互作用,使系统功能模块相对独立。高内聚 低耦合

  • 合成复用法则

尽量使用合成/聚合的方式,而不是继承的方式

public Other{ public void show(); }
//需要在当前类中使用其他类的方法或变量时,尽量不采取继承,而是把其他类的引用声明为当前类的成员变量,通过构造方法来实现调用
public class Present /*extends Other*/ {
    private Other other;//合成复用
    public Present(Other other){
        this.other = other;
    }
    public void test(){
        //调用其他类中的show方法
        other.show();
    }
}

2.常用的设计模式

  • **创建型模式:**单例设计模式,工厂方法模式,抽象工厂模式
  • **结构型模式:**装饰器模式,代理模式
  • **行为型模式:**模板模式

2.1单例设计模式

  • 饿汉式:new对象时直接定义Object obj = new Object();
  • 懒汉式:(存在多线程同步处理的问题)new对象时不直接定义Object obj = null;
/**
 *懒汉式举例
 */
public class Singleton{
    //声明本类类型的引用指向本类类型的对象并使用private static修饰
    private static Singleton sin = null;
    //私有化构造方法
    private Singleton(){}
    //提供共有的get方法负责返回上述生成的对象
    public static /*synchronized*/ Singleton getInstance(){//……①
        synchronized(Singleton.class){//……②
            if(null == sin){
            	sin = new Singleton();
        	}
        	return sin;
    	}
    }        
}
	/**
	 *1.假设有多个线程同时访问getInstance方法,第一个线程还未创建完毕sin对象,后续的线程检测到sin = null成立,故最终会创建多个线程。
	 *2.可以在方法名前加synchronized关键字修饰加锁,如①所示。
	 *3.也可以在方法内部用synchronized修饰类名,如②所示。
	 */
//为防止每次调用getInstance方法都要加锁,首先判断sin是否为null,于是方法变成
public static /*synchronized*/ Singleton getInstance(){//……①
    if(null == sin){
        synchronized(Singleton.class){//……②
            if(null == sin){
            	sin = new Singleton();
        	}
    	}
    }
    return sin;
}       

2.2工厂方法模式

2.2.1普通工厂模式

建立一个工厂类,对实现了同一接口的不同实现类进行实例的创建

  • ***UML类图***的方法和属性的访问权限
    类图符号说明方法和属性访问权限示例
    普通工厂模式

SendFactory中produce方法返回的是Sender接口实现的MailSender类或SmsSender类

**注意:**如果传递到produce中的参数出错,则不能正确创建对象,并且可能出现空指针异常。

2.2.2多个工厂模式

多个工厂模式**主要缺点:**首先需要创建工厂类的对象。

2.2.3静态工厂模式

静态工厂模式

  • 适用于大量对象的创建
2.2.4抽象工厂模式

抽象工厂模式

2.3装饰器模式

**装饰器模式就是给一个对象动态地增加一些新功能,要求装饰对象和被装饰对象实现同一个接口,装饰对象有被装饰对象的实例。

***装饰器模式***是将原有对象作为一个参数传递给装饰器的构造器。

装饰器模式

public class Decorator implements Souceable {
    private Sourceable source;
    
    public Decorator(Sourceable source) {
        this.source = source;
    }
    
    @Override
    public void method() {
        soiurce.method();//保证原有功能不变的基础上增加修饰
        System.out.println("这里是修饰语句。");
    }
}
  • 可以实现类功能的扩展,缺点是会产生很多相似的类。

2.4代理模式

***代理模式***是在代理类中创建一个被代理的对象。

代理模式

  • 装饰器模式关注于在一个对象上动态地添加方法,而代理模式关注于控制对对象的访问。

2.5模板方法模式

一个抽象类中封装了一个固定流程,流程中的具体步骤可以由不同子类进行不同的实现,通过抽象类让固定的流程产生不同的结果。

模板方法模式

public class AbstractCalculator {
    public int splitExpression(String exp, String op) {//exp为运算式,op为其中的运算符
        String[] sArr = exp.split(op);
        return calculate(Integer.parseInt(sArr[0], Integer.parseInt(sArr[1])));//将分割开的两个运算数传递给calculate方法
    }
    
    //建立抽象方法,规范计算流程,由不同子类实现
    public abstract int calculate(int num_a, int num_b);
}
//-----------------------------------
public class Plus extends AbstractCalculator {
    @Override
    public int calculator(int num_a, int num_b) {
        return num_a + num_b;
    }
}
//-----------------------------------
public class AbstractCalculatorTest {
    public static void main(String[] args) {
        AbstractCalculator ac = new Plus();
        int res = ac.splitExpression("1+1", "\\+");
        System.out.println("运算结果是:" + res);
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值