活字印刷,面向对象
所有编程初学者都会有这样的问题,就是碰到问题就直觉地用计算机能够理 解的逻辑来描述和表达待解决的问题及具体的求解过程。这其实是用计算机的方式去思 考,比如计算器这个程序,先要求输入两个数和运算符号,然后根据运算符号判断选择如 何运算,得到结果,这本身没有错,但这样的思维却使得我们的程序只为满足实现当前的 需求,程序不容易维护,不容易扩展,更不容易复用。从而达不到高质量代码的要求。
第一,要改,只需更改要改之字,此为可维护 ;第二,这些字并非用完这次就无 用,完全可以在后来的印刷中重复使用,此乃可复用 ;第三,此诗若要加字,只需另刻 字加入即可,这是可扩展 ;第四,字的排列其实可能是竖排可能是横排,此时只需将活 字移动就可做到满足排列需求,此是灵活性好 。
简单工厂模式uml图
// 步骤1. 创建抽象产品类,定义具体产品的公共接口
abstract class Product{
public abstract void Show();
}
//步骤2. 创建具体产品类(继承抽象产品类),定义生产的具体产品
//具体产品类A
class ProductA extends Product{
@Override
public void Show() {
System.out.println("生产出了产品A");
}
}
//具体产品类B
class ProductB extends Product{
@Override
public void Show() {
System.out.println("生产出了产品C");
}
}
//具体产品类C
class ProductC extends Product{
@Override
public void Show() {
System.out.println("生产出了产品C");
}
}
//步骤3. 创建工厂类,通过创建静态方法从而根据传入不同参数创建不同具体产品类的实例
class Factory {
public static Product Manufacture(String ProductName){
//工厂类里用switch语句控制生产哪种商品;
//使用者只需要调用工厂类的静态方法就可以实现产品类的实例化。
switch (ProductName){
case "A":
return new ProductA();
case "B":
return new ProductB();
case "C":
return new ProductC();
default:
return null;
}
}
}
//步骤4. 外界通过调用工厂类的静态方法,传入不同参数从而创建不同具体产品类的实例
//工厂产品生产流程
public class SimpleFactoryPattern {
public static void main(String[] args){
Factory mFactory = new Factory();
//客户要产品A
try {
//调用工厂类的静态方法 & 传入不同参数从而创建产品实例
mFactory.Manufacture("A").Show();
}catch (NullPointerException e){
System.out.println("没有这一类产品");
}
//客户要产品B
try {
mFactory.Manufacture("B").Show();
}catch (NullPointerException e){
System.out.println("没有这一类产品");
}
//客户要产品C
try {
mFactory.Manufacture("C").Show();
}catch (NullPointerException e){
System.out.println("没有这一类产品");
}
//客户要产品D
try {
mFactory.Manufacture("D").Show();
}catch (NullPointerException e){
System.out.println("没有这一类产品");
}
}
}
优点
- 将创建实例的工作与使用实例的工作分开,使用者不必关心类对象如何创建,实现了解耦;
- 把初始化实例时的工作放到工厂里进行,使代码更容易维护。 更符合面向对象的原则 & 面向接口编程,而不是面向实现编程。
缺点
- 工厂类集中了所有实例(产品)的创建逻辑,一旦这个工厂不能正常工作,整个系统都会受到影响;
- 违背“开放 - 关闭原则”,一旦添加新产品就不得不修改工厂类的逻辑,这样就会造成工厂逻辑过于复杂。
- 简单工厂模式由于使用了静态工厂方法,静态方法不能被继承和重写,会造成工厂角色无法形成基于继承的等级结构。
首先你看那个‘动物’矩形框,它就代表一个类(Class)。类图分三层,第一 层显示类的名称,如果是抽象类,则就用斜体显示。第二层是类的特性,通常就是字段和 属性。第三层是类的操作,通常是方法或行为。注意前面的符号,‘+’表示public,‘-’表示 private,‘#’表示protected。
然后注意左下角的‘飞翔’,它表示一个接口图,与类图的区别主要是顶端有 >显示。第一行是接口名称,第二行是接口方法。接口还有另一种表示方法, 俗称棒棒糖表示法,比如图中的唐老鸭类就是实现了‘讲人话’的接口。
接下来就可讲类与类,类与接口之间的关系了。你可首先注意动物、鸟、 鸭、唐老鸭之间关系符号。它们都是继承的关系,继承关系用空心三角形+实线来表示。实现接口用空 心三角形+虚线来表示。
你看企鹅和气候两个类,企鹅是很特别的鸟,会游不会飞。更重要的是,它 与气候有很大的关联。我们不去讨论为什么北极没有企鹅,为什么它们要每年长途跋涉。 总之,企鹅需要‘知道’气候的变化,需要‘了解’气候规律。当一个类‘知道’另一个类时,可 以用关联(association)。关联关系用实线箭头来表示。
聚合 关系用空心的菱形+实线箭头来表示。
合成(Composition,也有翻译成‘组合’的)是一种强的‘拥有’关系,体现了 严格的部分和整体的关系,部分和整体的生命周期一样 [DPE]。在这里鸟和其翅膀就是 合成(组合)关系,因为它们是部分和整体的关系,并且翅膀和鸟的生命周期是相同的。合成关系用实心的菱形+实线箭头来表示。
动物几大特征,比如有新陈代谢,能繁殖。而动物要有生命力,需要氧气、 水以及食物等。也就是说,动物依赖于氧气和水。他们之间是依赖关系(Dependency), 用虚线箭头来表示。