** 简述 设计模式 七大原则 **
1.开发封闭原则 : 对扩展开放 , 对修改封闭。 在程序需要就行扩展的时候 , 不能去修改 原有的代码, 形成一个 热插拔 的效果。 2.单一职责原则: 一个类 接口 或 方法 只负责 一个 职责 ,降低代码复杂度 以及 变更引起的风险。 3.依赖倒置原则: 针对接口编程 , 依赖于 抽象类 或 接口 而不依赖于 具体实现类。 4.接口隔离原则: 将不同 功能 定义在不同接口中 实现 接口隔离。 5.里氏替换原则: 任何 基类 可以出现的 地方 ,子类 都一定可以 出现。 6.迪米特原则: 每个模块 都要 对 其他模块 尽可能 少地 了解 或 依赖 ,降低 代码耦合度。 7.合成复用原则: 尽量 使用 组合/聚合 而不是 继承 达到 软件复用 的 目的。
** 简述 设计模式 的 分类 **
1.创建型模式: 在创建对象的 同时 隐藏 逻辑 ,不使用 new 直接 实例化对象 。
有(工厂方法模式 抽象工厂模式 单例模式 建造者模式 原型模式)
2.结构型模式: 通过 类和接口 间的 继承和引用 实现 创建 复杂结构的对象。
有 (适配器模式 装饰器模式 代理模式 外观模式 桥接模式 组合模式 享元模式)
3.行为型模式: 通过 类之间 不同 的 通信方法 实现 不同行为。
有 (策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式)
** 什么 是 策略 模型 ? **
策略模型 定义了 算法族, 分别封装起来,让他们之间 可以相互 替换 ,
此模式让 算法的 变化 独立 于 使用 算法的客户。
优点 : 遵循了 开闭原则 ,扩展性好。
缺点 : 随着 策略的 增加, 对外暴露越来越多。
以生活中的例子来说,比如我们要出去旅游,选择性很多,可以选择骑车、开车、坐飞机、坐火车等,就可以使用策略模式,把每种出行作为一种策略封装起来,后面增加了新的交通方式了,如超级高铁、火箭等,就可以不需要改动原有的类,新增交通方式即可,这样也符合软件开发的开闭原则。 策略模式实现代码如下:
interface ITrip {
void going();
}
class Bike implements ITrip {
@Override
public void going() {
System.out.println("骑自行车");
}
}
class Drive implements ITrip {
@Override
public void going() {
System.out.println("开车");
}
}
class Trip {
private ITrip trip;
public Trip(ITrip trip) {
this.trip = trip;
}
public void doTrip() {
this.trip.going();
}
}
public class StrategyTest {
public static void main(String[] args) {
Trip trip = new Trip(new Bike());
trip.doTrip();
}
}
public abstract class Duck {
//接口
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public abstract void display();
public void swim()
{
System.out.println("all duck float,evendecoys");
}
public void performFly(){
flyBehavior.fly();
}
public void performQucak(){
quackBehavior.quack();
}
public FlyBehavior getFlyBehavior() {
return flyBehavior;
}
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
public QuackBehavior getQuackBehavior() {
return quackBehavior;
}
public void setQuackBehavior(QuackBehavior quackBehavior) {
this.quackBehavior = quackBehavior;
}
}
public class MallardDuck extends Duck{
@Override
public void display() {
System.out.println("i am real Mallard duck");
}
public MallardDuck() {
flyBehavior=new FlyWithWings();
quackBehavior=new Qucak();
}
}
public class ModeDuck extends Duck{
@Override
public void display() {
System.out.println("i am Model duck");
}
public ModeDuck() {
flyBehavior=new FylNoWay();
quackBehavior=new Qucak();
}
}
public interface FlyBehavior {
public void fly();
}
public class FlyRockPowered implements FlyBehavior{
@Override
public void fly() {
System.out.println("iam flying with a rocket");
}
}
public class FlyWithWings implements FlyBehavior{
@Override
public void fly() {
System.out.println("I can fly");
}
}
public class FylNoWay implements FlyBehavior{
@Override
public void fly() {
System.out.println("i am can not fly");
}
}
public interface QuackBehavior {
public void quack();
}
public class Qucak implements QuackBehavior{
@Override
public void quack() {
System.out.println("Qucak");
}
}
public class MinDuckSimulator {
public static void main(String[] args) {
Duck duck=new MallardDuck();
duck.performQucak();
duck.performFly();
duck.swim();
duck.display();
Duck model=new ModeDuck();
model.performFly();
model.setFlyBehavior(new FlyRockPowered());
model.performFly();
}
}
**单例模式 **
public class Singletion {
//双层检查加锁
//volatile 确保 uniqueInstance 变量被初始化 成 Singletion实例时候,多个线程能正确处理 uniqueInstance 变量
private volatile static Singletion uniqueInstance;
private Singletion(){};
public static Singletion getInstance(){
//检查实例 如果不存在就进入同步框块
if(uniqueInstance == null){
//只有第一次才彻底执行这里
synchronized(Singletion.class){
//进入区块后,再检查一次,如果还是null,才创建实例
if(uniqueInstance ==null){
//进入区块后,再检查一次,如果还是null,才创建实例
uniqueInstance=new Singletion();
}
}
}
return uniqueInstance;
}
}
单例模式 确保程序中 一个类 最多只有一个实例。
单例模式 也提供 访问 这个实例的 全局点。
在java 中 实现单例模式 需要私有构造器 ,一个静态方法和静态变量
确定性能和资源上的限制 ,然后小心选择适当的 方式 实现 单例模式,以解决多线程问题。
** 实现一:立即加载 / “饿汉模式” **
立即加载就是使用类的时候已经将对象创建完毕(不管以后会不会使用到该实例化对象,先创建了再说。很着急的样子,故又被称为“饿汉模式”),常见的实现办法就是直接new实例化。
public class Singleton {
// 将自身实例化对象设置为一个属性,并用static、final修饰
private static final Singleton instance = new Singleton();
// 构造方法私有化
private Singleton() {}
// 静态方法返回该实例
public static Singleton getInstance() {
return instance;
}
}
饿汉模式”的优缺点:
优点:实现起来简单,没有多线程同步问题。 缺点:当类SingletonTest被加载的时候,会初始化static的instance,静态变量被创建并分配内存空间,从这以后,这个static的instance对象便一直占着这段内存(即便你还没有用到这个实例),当类被卸载时,静态变量被摧毁,并释放所占有的内存,因此在某些特定条件下会耗费内存。
** 实现二:延迟加载 / “懒汉模式” **
延迟加载就是调用get()方法时实例才被创建(先不急着实例化出对象,等要用的时候才给你创建出来。不着急,故又称为“懒汉模式”),常见的实现方法就是在get方法中进行new实例化。
public class Singleton {
// 将自身实例化对象设置为一个属性,并用static修饰
private static Singleton instance;
// 构造方法私有化
private Singleton() {}
// 静态方法返回该实例
public static Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
“懒汉模式”的优缺点:
优点:实现起来比较简单,当类SingletonTest被加载的时候,静态变量static的instance未被创建并分配内存空间,当getInstance方法第一次被调用时,初始化instance变量,并分配内存,因此在某些特定条件下会节约了内存。 缺点:在多线程环境中,这种实现方法是完全错误的,根本不能保证单例的状态。
** 实现三:线程安全的“懒汉模式” **
public class Singleton {
// 将自身实例化对象设置为一个属性,并用static修饰
private static Singleton instance;
// 构造方法私有化
private Singleton() {}
// 静态方法返回该实例,加synchronized关键字实现同步
public static synchronized Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
优点:在多线程情形下,保证了“懒汉模式”的线程安全。 缺点:众所周知在多线程情形下,synchronized方法通常效率低,显然这不是最佳的实现方案。



