SAF 中抽象工厂的实现(Remoting的实体统一由服务器端实现)

Storage Access Framework Android API GuideAndroid 4.4 引入了存储访问框架Storage Access Framework(SAF),云或本地存储服务可以实现DocumentProvider来分装他们的服务以便加入到该生态系统中。SAF包含了 Document Provider, Android 包含几个内置的DocumentsProvider,注入下载Downloads, Images, Vi 阅读详情

来自:http://www.tracefact.net/Software-Design/SAF-Abstract-Factory.aspx

引言

本文是《Developing Application Frameworks in .NET》的读书笔记。SAF 是书中的一个范例框架,意为 Simple Application Framework(简单应用程序框架)。这篇文章主要向大家说明了SAF中抽象工厂模式的实现方式。

设计思想概述

抽象工厂是很常用的一种创建型模式,它的主要作用在于向程序员屏蔽了创建对象的复杂细节,在获取对象时,只需要在工厂类上调用 GetXXX(),或者 CreateXXX(),便可以得到一个类型实例,而不是通常所使用的new XXX()这种方式。关于抽象工厂更详细的内容可以参考 奇幻RPG(人物构建与Abstract Factory模式) 这篇文章。SAF 的抽象工厂也是基于GOF的这个基本模型,但是做了下面两个改进:

利用反射,根据字符串动态创建工厂

我们获得工厂类时,通常还是通过AbstractFactory factory = new ConcreteFactory()这种方式获得。这样如果我们想更换一个工厂实体类时,比如说,将上面的ConcreteFactory换成 AnotherFactory,我们需要修改代码为 AbstractFactory factory = new AnotherFactory(),这样免不了需要再次重新进行编译。

在SAF中,使用了自定义Config配置节点,将 工厂名称 和 它的类型信息(所在的程序集、命名空间、类型名称)全部保存在了App.Config文件中,并创建相应的ClassFactoryConfiguration 类型用于获取App.Config中的节点信息。然后创建ClassFactory类型,并在其中添加静态方法GetFactory(string name),其中name代表了工厂名称(必须与App.Config中保存的名称匹配)。然后,在客户端调用这个方法来创建工厂。通过这种方式,我们只需要在Config中保存所有的工厂类信息,然后就可以为GetFactory()通过传入不同的参数,创建不同的工厂类。

实际的流程如下:

  1. 客户端程序调用  ClassFactory.GetFactory(string factoryName) 方法,传入工厂名称。
  2. 在GetFactory() 方法中一个ClassFactoryConfiguration对象,这个对象封装了获取app.Config中信息的方法。
  3. ClassFactoryConfiguration 根据 factoryName参数在app.Config中寻找与工厂名称匹配的节点,找到后,返回该工厂的类型信息。
  4. GetFactory()方法根据类型信息,使用反射创建类型实例,然后返回该实例。

使用Remoting创建远程工厂

SAF中的另一个改进是引入了Remoting,关于Remoting的详细内容,可以参考 .Net中的Remoting 这篇文章。有的时候,我们需要使用Remoting获取位于远程服务器中的对象,这时往往需要写一些注册Channel、转换对象类型的代码。SAF的抽象工厂将这些细节也屏蔽了起来,只要将获取远程对象的地址写在配置文件中,比如http://localhost:8989/ClassFactory,剩下的步骤与使用本地对象别无二致,极大的简化了操作。

接下来我们看一下代码实现。

代码实现

抽象工厂类的实现

首先是创建抽象工厂类的体系,新建一个解决方案ClassFactory,再其下建立一个类库项目 Factory,它包含了下面一些类,以构成一个基本的抽象工厂模式,作为范例:

namespace Factory { 
    /* 工厂基类
     * **************************************************/
    public abstract class ProductFactory : MarshalByRefObject{
        public abstract Product GetCheapProduct();
        public abstract Product GetExpensiveProduct();
    }

    // 工厂实体类 (一般产品)
    public class ConcreteProductFactory : ProductFactory {
        public override Product GetCheapProduct() {
            return new CheapProduct();
        }
        public override Product GetExpensiveProduct() {
            return new ExpensiveProduct();
        }
    }

    // 工厂实体类 (新产品)
    public class ConcreteNewProductFactory : ProductFactory {
        public override Product GetCheapProduct() {
            return new NewCheapProduct();
        }
        public override Product GetExpensiveProduct() {
            return new NewExpensiveProduct();
        }
    }

    // 工厂实体类 (远程产品) 使用Remoting
    public class ConcreteRemoteProductFactory : ProductFactory {
        public override Product GetCheapProduct() {
            return new RemoteCheapProduct();
        }
        public override Product GetExpensiveProduct() {
            return new RemoteExpensiveProduct();
        }
    }

    /* 产品基类 MashalByRefObject
     * **************************************************/
    public abstract class Product : MarshalByRefObject {
        public abstract string Name { get; }
        public abstract int GetPrice();
        public abstract string GetColor();
    }

    // 一般产品实体类 ( 由 ConcreteProductFactory 创建 )
    public class CheapProduct : Product { 
        private const int cost = 10;
        private const string color = "red";
        private const string name = "Cheap Product";

        public override int GetPrice() {
            return cost * 2;
        }
        public override string GetColor() {
            return color;
        }
        public override string Name {
            get {
                return name;
            }
        }
 }

    // 一般产品实体类 ( 由 ConcreteProductFactor 创建 )
    public class ExpensiveProduct : Product { /* 实现略 */ }

    // 新产品实体类 ( 由 ConcreteNewProductFactory 创建 )
    public class NewCheapProduct : Product { /* 实现略 */ }

    // 新产品实体类 ( 由 ConcreteNewProductFactory 创建 )
    public class NewExpensiveProduct : Product { /* 实现略 */ }
    
    // 远程产品实体类 ( 由 ConcreteRemoteProductFactory 创建 )
    public class RemoteCheapProduct : Product { /* 实现略 */ }

    // 远程产品实体类 ( 由 ConcreteRemoteProductFactory 创建 )
    public class RemoteExpensiveProduct : Product { /* 实现略 */ }
}

这里需要注意的是 ProductFactory和 Product 抽象类均继承自 MarshalByRefObject 基类,这是因为这两个类的子类实现有一部分位于客户端、还有一部分位于服务器端,为了能从服务器端向客户端进行封送(Marshal),它们必须声明为继承自MarshalByRefObject。

我们注意到上面这段程序的两个 远程产品实体类(RemoteCheapProduct和RemoteExpensiveProduct) 应该是仅存在于服务器端的,等下我们会细说这里。现在我们编译上面的代码,会在Bin目录下生成Factory.dll文件。

服务器端的实现

服务器端的实现很简单,仅仅是开启Remoting服务,供客户端进行调用就可以了。在上面已经说明,服务器端仅需要提供两个远程产品实体类(RemoteCheapProduct 和 RemoteExpensiveProduct),所以只需要提供一个 ConcreteRemoteProductFactory 工厂类型就可以了。现在我们再创建一个解决方案,名为FactoryServer,在其下添加一个Console控制台项目RemoteServer,接下来,我们 把上一步生成的Factory.dll 文件复制到Bin目录下,然后引用它(不要引用项目)。

这里需要注意:因为Factory包含了远程所要提供的对象,所以我们需要引用它;而它也包含了客户端可以直接创建的对象,所以客户端也需要引用Factory.dll,但是我们不能将Factory服务器端所提供的内容交给客户端(如果可以的话,我们根本用不着Remoting),所以我们在客户端引用Factory之前要屏蔽掉服务器端实现的内容。如果直接引用项目(服务器端、客户端同时引用了Factory项目),一是没有起到服务端、客户端分离的作用,二是一旦我们屏蔽掉Factory项目中的内容,那么重新生成之后,服务器端也丧失了这些内容(所以我们在屏蔽部分内容之前将生成好的dll复制到FactoryServer的Bin目录下,然后引用之)。

服务器端通过配置的方式开启Remoting服务,app.Config中的配置如下:

<system.runtime.remoting>
    <application>
        <service>
            <wellknown 
                mode="Singleton"
                  type="Factory.ConcreteRemoteProductFactory, Factory"
                  objectUri="ClassFactory" />
        </service>
        <channels>
            <channel ref="http" port="8989"/>
        </channels>
    </application>
</system.runtime.remoting>

接着,编写Program代码,仅仅是根据配置开启服务而已:

public class Program {
    static void Main(string[] args) {
        // 根据 App.config.exe 中的配置开启远程服务
        RemotingConfiguration.Configure("RemoteServer.exe.config", false);

        Console.WriteLine("远程服务成功开启!");
        Console.ReadLine();
    }
}

客户端的实现

我们在上面 抽象工厂类 的实现中,已经创建了一个解决方案ClassFactory,以及其下的Factory项目。我们将ClassFactory解决方案整体视为客户端,此时,客户端不应包含服务端的代码实现(RemoteCheapProduct类 和 RemoteExpensiveProduct类),所以我们将它删除或者注释掉。另外,由于Config中保存的类型信息是工厂类型的信息,比如ConcreteRemoteProductFactory类型的信息,所以当我们通过反射创建远程工厂类型的实例时,客户端依然需要ConcreteRemoteProductFactory的类型信息,所以我们不能屏蔽掉ConcreteRemoteProductFactory,但是我们可以让它什么都不做(Empty Class),现在修改ConcreteRemoteProductFactory 如下所示:

// 工厂实体类 (远程产品) 使用Remoting
public class ConcreteRemoteProductFactory : ProductFactory {
    public override Product GetCheapProduct() {
        throw new Exception("由服务器端实现");
    }
    public override Product GetExpensiveProduct() {
        throw new Exception("由服务器端实现");
    }
}

这个类仅仅是为了在客户端提供一个类型信息,以便能够通过反射创建类型,实际上只要访问的是服务器端,那么这里永远都不会抛出异常,因为这个类实际是在服务器端创建的。

现在修改app.config文件,记录我们所有的工厂类的 名称 及类型信息。名称可以任意起,在创建类型的时候调用的GetFactory(string name)方法的name参数要与这里匹配;类型信息必须为客户端拥有的工厂类类型,用于通过反射创建对象:

<configSections>
    <section name="classFactory" type="ConfigManager.ClassFactorySectionHandler, ConfigManager" />
</configSections>

<classFactory>
    <factory name="ProductFactory-A" type="Factory.ConcreteProductFactory, Factory" />
    <factory name="ProductFactory-B" type="Factory.ConcreteNewProductFactory, Factory" />
    <factory name="Remote-ProductFactory-C" location="http://localhost:8989/ClassFactory" type="Factory.ConcreteRemoteProductFactory, Factory" />
</classFactory>

注意到name属性为" Remote-ProductFactory-C "的节点,它拥有一个location属性,这个属性保存了获取它的远程地址,用于Remoting访问。

接下来,我们要创建对这个节点的处理程序,ClassFactorySectionHandler。在ClassFactory解决方案下再添加一个类库项目:ConfigManager,然后添加ClassFactorySectionHandler类,它用于处理节点(如不清楚,可以参考 .Net自定义应用程序配置):

// 结点处理程序,在调用 ConfigurationManager.GetSection("sectionName") 自动调用这里
public class ClassFactorySectionHandler : IConfigurationSectionHandler {
    public object Create(object parent, object configContext, XmlNode section) {
        return new ClassFactoryConfiguration(section);
    }
}

// 结点配置程序
public class ClassFactoryConfiguration {
    private XmlNode node;

    // 这里的 node 为 classFactory 结点
    public ClassFactoryConfiguration(XmlNode section) {
        this.node = section;
    }

    // 获取与name属性匹配的子结点的 type 属性
    public string GetFactoryType(string name) {

        // 获取子结点,使用 XPath 语法查找
        XmlNode childNode = node.SelectSingleNode("factory[@name='" + name + "']");

        if (childNode != null && childNode.Attributes["type"] != null)
            return childNode.Attributes["type"].Value;
        else
            return null;
    }

    // 获取与name属性匹配的子结点的 location 属性 
    // location 属性指定远程对象的获取位置
    public string GetFactoryLocation(string name) {
        // 获取子结点,使用 XPath 语法查找
        XmlNode childNode = node.SelectSingleNode("factory[@name='" + name + "']");

        if (childNode != null && childNode.Attributes["location"] != null)
            return childNode.Attributes["location"].Value;
        else
            return null;
    }
}

我们只需要注意两个方法就可以了:GetFacotryType(string name),获取工厂类的类型,用于通过反射创建类型;GetFactoryLocation(string name),获取工厂类的地址,用于Remoting。

接下来我们在解决方案下再创建一个控制台项目,Main,它是我们的客户程序。在其下创建ClassFactory类,我们的所有客户端代码实际上通过这个类的静态方法GetFactory(string name)获取工厂类:

public class ClassFactory {
    // 不允许使用 new 创建
    private ClassFactory() {}
    
    // 根据结点的name属性创建Factory对象
    public static object GetFactory(string name) {
        object factory = null;

        // 获取配置对象
        ClassFactoryConfiguration config = 
    (ClassFactoryConfiguration)ConfigurationManager.GetSection("classFactory");

        // 获取Factory位置,用于Remoting远程对象
        string location = config.GetFactoryLocation(name);

        // 获取Factory类型
        string type = config.GetFactoryType(name);

        if(type == null) return null;

        Type t = Type.GetType(type);

        try {
            if (location != null) {
                factory = Activator.GetObject(t, location);    // 创建远程对象
            } else {
                factory = Activator.CreateInstance(t);         // 创建本地对象
            }
        }
        catch {
            throw new Exception("使用反射创建对象失败!");
        }

        return factory;
    }
}

代码测试

现在我们对代码进行一下测试:

public class Program {
    static void Main(string[] args) {

        // 创建根据配置创建工厂类
        ProductFactory pfA = (ProductFactory)ClassFactory.GetFactory("ProductFactory-A");
        ProductFactory pfB = (ProductFactory)ClassFactory.GetFactory("ProductFactory-B");
        ProductFactory pfC = (ProductFactory)ClassFactory.GetFactory("Remote-ProductFactory-C");

        // 创建本地产品
        Product p1 = pfA.GetCheapProduct();
        Product p2 = pfA.GetExpensiveProduct();
        Product p3 = pfB.GetCheapProduct();
        Product p4 = pfB.GetExpensiveProduct();

        // 创建远程产品
        Product p5 = pfC.GetCheapProduct();
        Product p6 = pfC.GetExpensiveProduct();

        // 打印产品
        PrintDescription(p1);
        PrintDescription(p2);
        PrintDescription(p3);
        PrintDescription(p4);

        // 打印远程产品
        PrintDescription(p5);
        PrintDescription(p6);

        Console.WriteLine("Press enter to finish");
        Console.ReadLine();
    }

    private static void PrintDescription(Product p) {
        Console.WriteLine("{0}", p.Name);
        Console.WriteLine("---------------------------");
        Console.WriteLine("Color: {0}", p.GetColor());
        Console.WriteLine("Price: {0} \n", p.GetPrice());
    }
}

在运行之前,先运行服务端,然后再运行客户端,可以得到下面的输出结果:

Cheap Product
---------------------------
Color: red
Price: 20

Expensive Product
---------------------------
Color: red
Price: 100
// 略 ...
Press enter to finish

感谢阅读,希望这篇文章可以为你带来帮助!


c#三层+抽象工厂实现+类似抽象工厂反射实现 c#三层+抽象工厂实现+类似抽象工厂反射实现 大家可以看看,很不错,顺便做个广告,希望大家愿意交流的加小弟qq 9480007, 也可以进qq群 46301976 或 76055852 立即下载

相关推荐

C#三层架构经典源代码

C#三层架构经典源代码

java saf,SAF框架介绍,SAF框架使用详解

由于工作的关系,经常要跟SAF框架打交道,网上查了之后才发现只有简短的几篇介绍,说是加拿大的人开发的,经常开发CRM系统,早在01年就开始开源了,功能很强大。之前写过一篇,怎么学习一个新的PHP框架,下面说说SAF框架的大致流程吧。一,在/inc/config.xml里面添加一个ActionPath就是浏览器index/XXX后面浏览的uriType就是对应的一个控制器Forward用于实例化sm...

weixin_32897341的博客 1860

抽象工厂模式实现代码(利用了反射)

抽象工厂的目的是要提供一个创建一系列相关或相互依赖对象的接口,而不需要指定它们具体的类。将抽象工厂类中的条件判断语句,用.NET中发射机制代替。抽象工厂模式实现代码(利用了反射)

你可能不知道的console命令 详解~

在实际开发中,我们基本上都是使用console.log来打印信息,但是处理意外,还有很多其他的方法,这里我也是摸鱼时间总结了一下。

qq_24418107的博客 316

remote_factory_girl:从客户端创建 RemoteFactoryGirl 工厂

远程工厂女孩 面向(SOA) 的 。 当与结合使用时,用远程创建测试数据。 入门 有关安装和配置的信息,请参阅 。 运行测试 $ rspec 贡献 分叉它( ) 创建您的功能分支( git checkout -b my-new-feature ) 提交您的更改( git commit -am 'Add some feature' ) 推送到分支( git push origin my-new-feature ) 创建新的拉取请求 待办事项

科技中介服务机构如何提升客户在技术评估与需求匹配环节的服务效率与专业度.docx

科技中介服务机构如何提升客户在技术评估与需求匹配环节的服务效率与专业度

长文揭秘 让人忽略的Console对象

它接受一个数组或对象作为参数,并将其内容以表格的形式显示在控制台中,其中数组的每一项或对象的每一个属性将对应表格的一列。中,展现的动画,并不会影响网站的性能,因为这些代码只会在控制台打开时运行,这对正常使用网站的用户而言是无感的,并不会影响用户的正常体验。对象的方法,用于在控制台输出不同类型的信息,以便于开发者进行调试和查看程序执行过程中的各种状态。是用于在控制台输出指定对象的属性列表的方法,在需要查看某些对象的属性的时候很有用,例如下面使用。方法用于创建一个新的分组,将相关的输出信息分组显示在控制台中。

公众号:前端蛋卷 1739

WIN下使用visual studio 2022安装GMSSL命令行工具

2.1 使用管理员权限打开visual studio(非常重要,否则最后一步 nmake install会失败)右键vs2022,以管理员身份运行即可。2.4 配置环境变量,gmssl可执行程序默认会被安装到如下目录。将如下路径添加到系统环境变量即可。添加后的环境变量如下。2.编译解压后的gmssl源码,编译过程主要参考install.md中的内容,README.md中的步骤不完整。2.2 打开vs2022的命令终端,右键文件,选择在终端中打开。1.下载gmssl源码,解压到相应目录。

qq_45794382的博客 1269

safer_rails_console 使用指南

safer_rails_console 使用指南 safer_rails_console 是一个专为 Ruby on Rails 应用设计的安全增强工具,旨在减少在特定环境(如生产环境)中使用Rails控制台时的风险。本指南将带领您了解项目的基本结构、启动流程以及配置方式。 1. 项目目录结构及介绍 safer_rails_console作为一个Gem,其核心代码和资源主要分布在以下关键路径中: ...

gitblog_00832的博客 367

Windows版MySQL8.4.2LTS解压直用(下载免安装-绿色-项目打包直接使用-含卸载)

安装前运行微软常用运行库全集(也可能称为依赖)关于MySQL8中相关参数配置,可通过。选择8.5.2LTS长期服务版。选中密码,右键会直接复制。

xzzteach的博客 1440

企业知识库AI助手的权限管理架构:如何实现细粒度控制?

在展开架构设计前,我们需要先明确“细粒度权限”的核心定义,并理解它对AI助手的特殊意义。权限管理的“粒度”,本质是权限控制的精准程度。维度粗粒度权限细粒度权限资源范围entire document(整个文档)field/paragraph(字段/段落)操作类型read/write(读/写)generate_summary/download/export(生成摘要/下载/导出)上下文约束无(静态权限)time/ip/device(时间/IP/设备)适用场景简单系统(如内部wiki)

大数据洞察的博客 1042

[记]SAF 中抽象工厂的实现

SAF 中抽象工厂的实现 引言 本文是《Developing Application Frameworks in .NET》的读书笔记。SAF 是书中的一个范例框架,意为 Simple Application Framework(简单应用程序框架)。这篇文章主要向大家说明了SAF中抽象工厂模式的实现方式。 设计思想概述 抽象工厂是很常用的一种创建型模式,它的主要作用在于向程序员屏蔽了创...

weixin_34307464的博客 135

零成本矩阵玩法:1人运营5个账号的自动化工具链配置(2025全平台实战)

通过“AI内容生产+工具链分发+自动化变现”的组合拳,即使是新手也能实现1人运营5个账号的规模化收益。关键在于选对工具与设计标准化流程。未来,矩阵运营的竞争将聚焦于工具使用效率与数据洞察深度,快人一步者方能抢占先机!

TuFuir的博客 3785

图解C#中实现远程调用(Remoting)的示例代码(一)

图解C#中实现远程调用(Remoting)的示例代码(一)

【昆山人在上海】 4712

Kolla 容器化 高可用OpenStack 部署与 Ceph 集群集成

本文介绍了 Kolla 项目在容器化 OpenStack 部署和管理方面的应用,以及与 Ceph 集群的集成。Kolla 项目通过容器技术提供了一种简化和自动化的 OpenStack 部署方法,同时实现了易于升级和回滚的特点。本文还探讨了 Kolla 在实现零宕机升级方面的进展,并分析了其对 OpenStack 用户和社区的重要意义。

we22635的博客 2703

基于Harness Engineering构建AI Agent的全自动化CI_CD流水线

AI Agent的CI/CD是指对Agent的全生命周期资产(代码、Prompt、RAG知识库、模型权重、工具配置)进行持续集成、持续测试、持续发布和持续观测的自动化流程,核心目标是在保障发布质量的前提下,最大化提升Agent的迭代效率。

AI云原生与云计算技术学院 625

Remoting基本原理及其扩展机制(上)

.NET Remoting是.NET平台上允许存在于不同应用程序域中的对象相互知晓对方并进行通讯的基础设施。调用对象被称为客户端,而被调用对象则被称为服务器或者服务器对象。简而言之,它就是.NET平台上实现分布式对象系统的框架。传统的方法调用是通过栈实现,调用方法前将this指针以及方法参数压入线程栈中,线程执行方法时将栈中的参数取出作为本地变量,经过一番计算后,将方法的返回结果压入栈中。

vainnetwork的专栏 1044

微博scheme

微博scheme

qq_42278595的博客 319

回顾.NET Remoting分布式开发

记得在下第一次接触.NET Remoting分布式开发是在2003年,那时候是Framework1.0初次亮相之时,Remoting分布式开发是Framework1.0其中一个亮点。经过多年的发展,在2005年,WCF随着Framework2.0首先亮相。WCF是结合Remoting,Web服务,TCP/IP套接字,MSMQ信息,P2P,WSE等多方通讯的混合体。随着WCF的出现是否意昧着Remoting即将没落,答案是否定的。因为Remoting有其独到之处,在通讯效率,信息交换,安全性等多方面都有其特点

风尘浪子 2427

大数据分析利器:Tableau实战教程从入门到精通

你有3家分店,每月收集1000条销售数据(日期、分店、口味、销售额、订单数);想用Excel分析“哪家分店最赚钱”,但要做透视表→改格式→画柱状图,耗时30分钟,还经常因为公式错误返工;想看看“草莓味奶茶的月度销量趋势”,得手动筛选数据、调整折线图轴范围,稍不注意就漏看关键节点;想把分析结果分享给合伙人,Excel表格太抽象,对方盯着数字问“你到底想告诉我什么?

AI架构师小马 1493

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Microsoft .Net Remoting系列专题之一:.Net Remoting基础篇

我写的.Net Remoting系列专题: Microsoft .Net Remoting系列专题之二:Marshal、Disconnect与生命周期以及跟踪服务 Microsoft .Net Remoting系列专题之三:Remoting事件处理全接触 Microsoft .Net Remoting系列专题之一 一、Remoting基础 什么是Remoting,简而言之,我们可以将其看...

weixin_34200628的博客 416

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

.Net Remoting(分离服务程序实现) - Part.3

 分离服务程序集元信息和实现在上面Remoting基本操作的范例中,我们发现了这样一个情况:即是 客户应用程序 仍然需要引用 服务程序集(ServerAssembly),因为它需要DemoClass的元信息来创建代理。使用这种共享服务程序集的方式构建Remoting程序,其运行时的示意图如下所示:可以看到 宿主应用程序域(Host App Domain,位于服务端) 和 客户应用程

733

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

抽象工厂模式(Abstract Factory Pattern)

抽象工厂(Abstract Factory)角色:担任这个角色的是工厂方法模式的核心,它是与应用系统商业逻辑无关的。具体工厂(Concrete Factory)角色:这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。抽象产品(Abstract Product)角色:担任这个角色的类是工厂方法模式所创建的对象的父类,

diandian82的专栏 703

.NET Remoting程序开发入门篇(五)

客户端: public class ServerObject:MarshalByRefObject{ public ServerObj() {  throw new System.NotImplementedException(); } public Person GetPersonInfo(string name,string s...

weixin_33763244的博客 106

Remote建立分析

Remote作为一个远程调用对象技术,它有着.WebService没有的优势,首先它在一个企业内部系统使用的话,TCP通常就更好地发挥它的作用,当然它不跨平台这是一个不少的遗憾,下面是我对Remote的一点了解,有错误的地方大家指出来.. Remote通常分三步建立 1: RemoteObject(通常是类库文件) 2: RemoteServer(真正开发项目的时间建议用WINDOWS服务,...

weixin_30563917的博客 235
上一篇: 系统的横向结构和Websharp AOP(非常不错)
下一篇: How to Use FxCop
ArvinStudy
博客等级 码龄15年 83粉丝 193原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值