tag 标签: 设计模式

相关帖子
相关博文
  • 热度 6
    2021-3-6 19:38
    38552 次阅读|
    3 个评论
    前言: 设计模式已经经历了很长一段时间的发展,它们提供了软件开发过程中面临的一般问题的最佳解决方案。学习这些模式有助于经验不足的开发人员通过一种简单快捷的方式来学习软件设计。 一般我们会说设计模式一共有23种,总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 今天主要是分析 简单工厂模式、工厂模式和抽象工厂模式的区别,所以这里就简单介绍一下设计模式的概念。 作者:良知犹存 转载授权以及围观:欢迎添加微信公众号: 羽林君 网上 的很多资料都是在阐述着:工厂模式的好处就是解耦。相信大家对解耦这个词也不陌生,那解耦究竟有什么好处呢? 1.为了提高内聚(Cohesion)和松耦合(Coupling),我们经常会抽象出一些类的公共接口以形成抽象基类或者接口。这样我们可以通过声明一个指向基类的指针来指向实际的子类实现,达到了多态的目的。这里很容易出现的一个问题 n 多的子类继承自抽象基类,我们不得不在每次要用到子类的地方就编写诸如 new ×××;的代码。这里带来两个问题: 客户程序员必须知道实际子类的名称(当系统复杂后,命名将是一个很不好处理的问题,为了处理可能的名字冲突,有的命名可能并不是具有很好的可读性和可记忆性,就姑且不论不同程序员千奇百怪的个人偏好了)。程序的扩展性和维护变得越来越困难。 2.还有一种情况就是在父类中并不知道具体要实例化哪一个具体的子类。这里的意思为:假设我们在类 A 中要使用到类 B,B 是一个抽象父类,在 A 中并不知道具体要实例化那一个 B 的子类,但是在类 A 的子类 D 中是可以知道的。在 A 中我们没有办法直接使用类似于 new ×××的语句,因为根本就不知道×××是什么。 以上两个问题也就引出了工厂模式的两个最重要的功能: 定义创建对象的接口,封装了对象的创建; 使得具体化类的工作延迟到了子类中。 对于工厂模式,为了使其能更好的解决多种情况的问题,将其分为三类: 简单工厂模式(Simple Factory),工厂方法模式(Factory Method),抽象工厂模式(Abstract Factory) 。 GOAT 经常使用会遇到一些设计模式的使用,但是很少去细究里面的区别,这把就让我来大家分享一下,我认知中的这三种工厂模式。 简单工厂模式 我们把被创建的对象称为“产品”,把创建产品的对象称为“工厂”。如果要创建的产品不多,只要一个工厂类就可以完成,这种模式叫“简单工厂模式”。 结构定义: 是由一个工厂对象决定创建出哪一种产品类的实例。 简单工厂模式中包含的角色及其相应的职责如下: 工厂角色(Creator) :这是简单工厂模式的核心,由它负责创建所有的类的内部逻辑。当然工厂类必须能够被外界调用,创建所需要的产品对象。 抽象(Product)产品角色 :简单工厂模式所创建的所有对象的父类,注意,这里的父类可以是接口也可以是抽象类,它负责描述所有实例所共有的公共接口。 具体产品(Concrete Product)角色 :简单工厂所创建的具体实例对象,这些具体的产品往往都拥有共同的父类。 定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。这满足创建型模式中所要求的“创建与使用相分离”的特点。 结构图如下 范例如下: C++实现 #include using namespace std; enum Product_Type { Product1_, Product2_, }; class AbstractProduct //抽象(Product)产品角色 { public: AbstractProduct() {} virtual ~AbstractProduct() {} virtual void Show() = 0; }; class Product1 : public AbstractProduct //具体产品(Concrete Product)角色 { private: /* data */ public: Product1(/* args */); ~Product1(); void Show() { std::cout<< "product1"<
  • 热度 16
    2012-9-21 11:41
    1403 次阅读|
    0 个评论
      外观模式     Facade 2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31. Subsystemclasse* 33.34.35.36.37.//// 38.39.40.41.42.43.44.////// 45.46.47.48.49.50.51.////// 52.53. Test 55.56.57.58.59.60.61.62.63.64.65.////////// 66.67.68.69.70.71. resu*t 73.74.75.76.77.78.79.80.///////         fly1.action(1);                 Flyweight fly* = FlyweightFactory.getF*yweight("a");         System.out.println(fly1 == fly2);                 Flyweight fl*3 = FlyweightFactory.getFlywei*ht("b");         fly3.action(2);                 Flyweight fly4 = Flyweigh*Factory.getF*yweight("c");         fly4.action(3);                 Flyweigh* fly5 = FlyweightFactory.getFlyweight("d");         fly4.action(4);                 System.out.println(FlyweightFactory.getSize())*     } } result 参数值: 1 true 参数值: 2 *数值: 3 参数值: 4 4   11.代理模式:    引用普遍的解释(个人觉得这个模式还是很有用的,这种解释也很到位):为其他对象提供一种代理以控制对这个对象的访问。    然后贴上摘自网络的这种模式的适用场合:     1.远程代理(RemoteProxy)为一个对象在不同的地址空间提供局部代表。     2.虚*理(VirtualProxy)根据需*创建开销很大的对象。     3.保护代理(ProtectionProxy)控制对原始对象的访问。     4.智能指引(SmartReference)取代了简单的指针,它在访问对象时执行一些附加操作。   这个代理可以是一种引用,这个引用时的用户可以对于这个对象作出想要的操作。在代理这种模式下,其实还是有点像是对要代理的对象做一个继承,然后进行局部的改变。 例子代码:   Proxy public class ProxyObject implements Object {     Objec* obj;         public ProxyObject() {         System.out.println("这是代理类");         o*j = new ObjectImpl();     }         public void ac*ion() {         System.out.p*intln("代理开始");         obj.action*);         System.out.println(*代理结束");     } } Subject public interface Obje*t {     void action(); } RealSubject public class ObjectImpl implements Object {     pu*lic void action() {         System.out.println("========");         System.out.println("========");         System.out.pr*ntln("这是被代理的类");         System.out.println("========");         System.out.println("========");     } } Test public class Test {     publi* static void main() {         Object ob* = new ProxyObject();         obj.action();     * } result 这是代理类 代理开始 ======== =*====== 这是被代理的类 ======== ======*= 代理结束 /////////////////// ///////////////////// /////////////////////////////////////////////////////////////   /////////////////////////////////////////////////////////////////////////////////////////////////////
  • 热度 15
    2012-9-21 11:39
    1481 次阅读|
    0 个评论
      这是第二大类,结构性的模式,之前是创建型的模式。    适配器,顾名思义,也就是一种转接头,对对象的实现方法进行某种改进,以适应新的接口要求,期间重要的是转换的环节,也就是增加新的实现,当然这样的实现还是需要在之前的接口中进行声明,哈勒,下面是例子代码,有的时候觉得代码更能说明情况:   Target public interface Target {     void adapteeMethod();         void adapterMethod(); } Adaptee public class Adaptee {     public void adapteeMethod() {         Syste*.out.p*intln("Adaptee method!");     } } Adapt*r public clas* Adapter implement* Target {     private Adap*ee adaptee;         public Adapter(Adaptee adaptee) {         this.adapte* = adaptee;     }         public void adapteeMethod() {                adaptee.adapteeMethod();         }         public void adapterMethod() {                *ystem.out.println("Adapter method!");     } } Client public cla*s Test {     public stati* void main(String args) {                 Person man = new Man();                 Person lady = new Lady();                 Clothing jacket = new Ja*ket();                 Clot*ing trouser = new Trouser();                 jacket.personDressCloth(man);         trouser.personDressCloth(man);         j*cket.personDressCloth(lady);         trouser.personDressCloth(lady);     } } result 男人穿马甲 男人穿裤子 女人穿马甲 女人穿裤子     组合模式: 组合模式以树的形式(其实是一个ArrayList的操作),进行某些层次化的要求的操作,可以理解成为为某一个对象提供增加和删除的某种实现,代码如下:   Component p*blic abstract class Employer {     private String name;         public void setName(String name) {         this.name = *ame;     }         public String getName() {         return this.name;     }         public abstract void add(Employer employer*;         public abstract void delete(Employer employer);         public List employers;         public void printInfo*) {         System.out.println(name);     }         *ublic List getE*ployers() {         return this.employers;     } } Leaf public class Programmer extends Employer {     public Programmer(String name) {         setNam*(name);         employers = null;//程序员, 表示没有下属了     }     public v*id add(Employer employer) {             }     public void delete(Employer employer) {             } } public class Pro*ectAssistant extends Employer {     public ProjectAss*stant(String name) {         setName(name);         employers = *ull;//项目助理, 表示没有下属了     }     public void add(Employer employer) {             }     public void delet*(Employer employer) {             } } Composite public class Project*anager extends E*ployer {         public ProjectManager(String name) {         setName(name);         employers = new A*rayList();     }         public void add(Employer employer) {         employers.add(employer);     }     public void delete(Emplo*er employer) {         employers.remove(employer);     } } Clie*t publ*c class Test {     public st*tic void main(String args) {         Man man = new Man();         ManDecoratorA md1 = new ManDecoratorA();         ManDecoratorB md2 = n*w ManDecoratorB();                 md1.setPerson(man);         md2.setPerson(md1);         md2.eat();     } } result 男人在吃 再吃一顿饭 ManDecoratorA类 =============== ManDecoratorB类  
  • 热度 16
    2012-9-21 11:36
    1314 次阅读|
    0 个评论
    用Java是一件不算困难而且颇具回报的事情,笔者对此就是有一点亲身经历的,虽说在别的方面(例如在C的指针优势方面)Java是由不足,而且就效率来说,一般也是不算高,但是在帮助社区文档方面,笔者还是觉着Java做的确实很好,所以说现在看着Java的新的包的帮助文档就像在阅读一首诗一般美妙。 好了,闲话不多说,最近自己学习Java设计模式,就之前的编程来说,很少会去想到要重复利用的,可是最近越来越觉得Java中这一点倒是很重要的,首先,比如最近用的语音功能,就可以打包成一个jar文件,然后在下一次用的时候就只需要一个简单的import就可以了,而不是传统的复制代码,粘贴这么麻烦。 虽说编写Java程序有了好长的时间,但是真正去用到Java设计的思想还是不多,而现在眼前的23种,23种!设计模式让我大开眼界。 首先是工厂模式,工厂模式早有耳闻,像是一种生产的车间,在代码上,感觉有点绕,但是确实是一种很好的实现。 首先,创建product接口,可以定义一个方法,但是其实现是交给使用接口者使用的,这更像是一种策略,告诉你要做啥,怎么做是你自己的事。 而工厂的实现,就可以根据上面的描述进行,只不过product是一个工厂,在工厂中制定的方法就是生产,即得到要生产的物件,然后进行具体的生产。     *roduct public interface Work {     void doWork(); } ConcreteProduct public class StudentWork implements Work {     public void doWork() {         System.out.println("学生*作业!");     } } public class TeacherWork implements Work {     public void doWork() {         System.out.println("老师审批作业!");     } } Creator public interface IWorkFactory {     Work get*ork(); } Concre*eCreator pu*lic class StudentWorkFactory implements IWorkFactory {     public Work getWork() {         *eturn new StudentWork();     } } public class TeacherWorkFactory implements IWorkFactory {     public Work getWork() {         return new TeacherWork();     } } Test public class Test {     public static void m*in(Strin* args) {     IAnimalFactory blackAnimalFa*tory = new BlackAnimalFactory();     ICat blackCat = blackAnimalFactory.createCat();     blackCat.eat();     IDog blackD*g = blackAnimalFactory.createDog();     blackDog.eat();         IAnimalFactory whiteAnimalF*ctory = new WhiteAnimalFactory();     ICat whiteCat = whiteAnimalFactory.createCat();     whiteCat.eat();     IDog *hiteDog = whiteAnimalFactory.createDog();     whiteDog.eat(); } res*lt The bla*k cat is eating! Th* black dog is eatin*! The white cat is eating! The white dog is *ating!     建造者模式    示例代码:   Buil*er public interface PersonBuilder {     void buildHead();         v*id buildBody();         void buildFoot()*     Person buildPerson(); } ConcreteBuilder public class ManBuilder implements PersonB*ilder {     Person person;         public ManBuilder() {         person = ne* Man();     }         publ*c void build*ody() {         perso*.setBody("建造男人的身体");     }     public void buildFoot() {         person.setFo*t("建造男人的脚");     }     public void buildHead() {         pers*n.setHead("建造*人的头");     }     *ublic Person buildPerson() {         retur* person;     } } Dir*ctor public class PersonDirec*or {     public Person constructPerson(PersonBuilder pb) {         pb.buildHead();         pb.buildBody();         pb.buildFoot();         return pb.buildPerson();     } } Product public class Person {     private String head;         private String body;         private String foot;     public String getH*ad() {         return head;     }     public void setHead(String hea*) {         this.head = head;     }     public String getBody() {         return body;     }     public void setBody(String body) {         this.b*dy = body;     }     public String getFoot() {         return foot;     }     public void setFoot(String foot) {         t*is.foot = foot;     } } public class Man extends Person { } Test publ*c class Test{         public static void main(String args) {         Singleton sing = Singleton.getInstance();         Singleton si*g2 = Singleton.getI*stance();                 System.out.println(sing);         System.out.pr*ntln(sing2);     } } result singleton.Singleton@1c78e57 singleton.Singleton@1c78e57   原型模式: 原型模式也比较容易理解,也就是在设计时候首先加入肯定能用到的功能的声明,然后对其进行实现,最主要的是可以提供一份copy,也就是通过clone进行实现,这样在原基础上进行改动会比重新建立更为方便。     Prototype public class Prototype implements Cloneable {     private String name;         public void setName(String name) {         this.name = name;     }         public String getName() {         return this.name;     }     public Object clone(){         try {             return super.clone();         } catch (Exception e) {             e.printStackTrace();             return null;         }     } } ConcretePrototype publ*c class ConcretePrototype extend* Prototype {     public ConcretePrototype(String name) {         setName(name);     } } Client public clas* Test {     public static void main(String[] args) {         Prototype pro = new ConcretePrototy*e("prototype");         Prototype pro2 = (Prototype)pro.clone();         *ystem.out.println(pro.getName()*;         System.out.println(pro2.getName());     } } result prototype prototype  
相关资源