6大原则:
单一职责:一个类和方法只做一件事。 开闭原则:对修改关闭,对扩展开发。 里氏替换原则:子类可扩展新方法,但不可修改父类已有方法(父类已提供了具体实现的方法)。 依赖倒置:依赖于抽象,而非具体实现,即面向接口编程(如方法参数,类属性使用接口声明,这样可接收任何子类)。 接口隔离:使用多个隔离的接口定义抽象,降低耦合。 最少知道/迪米特原则:降低类之间的依赖,聚合,组合等。1:简单工厂设计模式
简单工厂模式并不是Gof23种设计模式中的一种,但也是一种设计模式废话,而且在实际工作中用的还是比较多的,所以从实用性角度来说,比较重要,有必要学习一下。
当对象创建比较复杂时,可以考虑使用简单工厂设计模式,简化客户端创建对象的复杂度,以及降低对象本身发生变化导致对象创建方式发生变对客户端的影响时也可以考虑使用简单工厂设计模式。
简单工厂模式的UML图如下:
下面看下如何将其翻译为具体的程序代码。
1.1:Product源码 。
public interface Product {
void show();
}
1.2:三个ConcreteProduct
public class ConcreteProduct1 implements Product {
@Override
public void show() {
System.out.println("一号产品显示。。。");
}
}
public class ConcreteProduct2 implements Product {
@Override
public void show() {
System.out.println("二号产品显示。。。");
}
}
public class ConcreteProduct3 implements Product {
@Override
public void show() {
System.out.println("三号产品显示。。。");
}
}
1.3:工厂类
public class SimpleFactory {
static final int PRODUCT_A = 1;
static final int PRODUCT_B = 2;
static final int PRODUCT_C = 3;
public static Product makeProduct(int kind) {
if (kind == PRODUCT_A) return new ConcreteProduct1();
if (kind == PRODUCT_B) return new ConcreteProduct2();
if (kind == PRODUCT_C) return new ConcreteProduct3();
return null;
}
}
1.4:客户端
public class Client {
public static void main(String[] args) {
SimpleFactory.makeProduct(1).show();
SimpleFactory.makeProduct(2).show();
SimpleFactory.makeProduct(3).show();
}
}
运行:
一号产品显示。。。 二号产品显示。。。 三号产品显示。。。1.5:优化
如果我们现在要增加四号产品,如下:
public class ConcreteProduct4 implements Product {
@Override
public void show() {
System.out.println("四号产品显示。。。");
}
}
则需要修改工厂类如下只保留新增代码:
public class SimpleFactory {
// ...
static final int PRODUCT_D = 4;
public static Product makeProduct(int kind) {
// ...
if (kind == PRODUCT_D) return new ConcreteProduct4();
return null;
}
}
产品类本身添加没有任何问题,因为添加的完全是全新类,但是修改工厂类明显不符合开闭原则,下面我们通过SPI 修改代码以满足开闭原则。
改造源码 。
首先创建meta-INFservicesdongshi.daddy.simplefactory.spi.Product,输入如下内容:
dongshi.daddy.simplefactory.spi.ConcreteProduct1 dongshi.daddy.simplefactory.spi.ConcreteProduct2 dongshi.daddy.simplefactory.spi.ConcreteProduct3
然后定义如下注解,用来唯一标识对象的key:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Key {
int id();
}
然后修改工厂类分别使用@Key注解设置其id值,如下:
@Key(id = 1)
public class ConcreteProduct1 implements Product {}
@Key(id = 2)
public class ConcreteProduct2 implements Product {}
@Key(id = 3)
public class ConcreteProduct3 implements Product {}
最后修改工厂类如下:
public class SimpleFactory {
private static Map productMap = new HashMap<>();
static {
ServiceLoader load = ServiceLoader.load(Product.class);
Iterator iterator = load.iterator();
while (iterator.hasNext()) {
Product next = iterator.next();
int id = next.getClass().getAnnotation(Key.class).id();
productMap.put(id, next);
}
}
public static Product makeProduct(int kind) {
return productMap.get(kind);
}
}
这样当我们增加一个新的产品类时只需要增加对应的类并使用@Key注解设置其id,然后将其类全限定名称设置到spi配置文件中就可以了。
参考文章列表简单工厂模式 。



