当前位置: 首页 > 知识库问答 >
问题:

设计模式的意见,这个项目的一个表存档

彭成天
2023-03-14

因此,我有以下项目要完成。但我还没有决定如何设计它。我想听听你的建议。

它基本上是一个表归档器。给定一定的条件,您需要将这些行导出到另一个地方。这个地方可能是另一个数据库或一个(s)ftp服务器。如果您选择一个数据库,那么每次达到某个限制(比如每个表不超过50k行)时,您都需要创建一个表,如果您选择一个(s)ftp服务器,那么您需要编写一个CSV或XML,并将文件放在那里。

所以我们有这些组合:

  1. sql2客户SQL
  2. sql2Oursql(为此,我们已经为连接和获取基于系统配置的一些信息进行了类)
  3. csv2ftp
  4. csv2sftp
  5. xml2ftp
  6. xml2sftp

现在,我看到抽象工厂模式到处都是,但基于什么?我的想法是,我应该有SQL写器,XML写字器,CSV写器,它们都继承自抽象的编写器类,该类实现了一些常见的策略,例如计数行数,获取通用配置参数等...我是否应该对连接类/接口执行相同的操作(因为 sql 和 (s)ftp 确实不同?

如果你需要更多的信息,尽管问。

共有3个答案

段干博明
2023-03-14

您正在处理两个问题。一个是格式,另一个是持久化的目标。对于格式,您需要序列化器,对于目标,您需要适配器。SqlSerializer、XMLseralizer。SQLDestination、FTPDestination atc。

代码看起来像这样:

>

  • Destination.persist(新的序列化程序(源数据));
  • Destination.persist(Serializer.transform(源数据));
  • 新目标(新序列化程序(源数据)).persist();

    interface DataSerializer{
        String serialize();
    }
    
    class SqlSerializer implements DataSerializer {
        final Object rawData;
    
        SqlSerializer(Object rawData) {
            this.rawData = rawData;
        }
    
        String serialize() {
            // SQL Serialization Logic
        }
    }
    
    class XmlSerializer implements DataSerializer {
        final Object rawData;
    
        XmlSerializer(Object rawData) {
           this.rawData = rawData;
        }
    
        String serialize() {
            // XML Serialization Logic
        }
    }
    
    interface Destination {
        void persist(DataSerializer dataSerializer);
    }
    
    class SqlDestination implements Destination {
        final String username;
        ...
        ...
    
        SqlDestination(String username, String password, String url) {
            this.username = username;
            ...
            ...
        }
    
        void persist(DataSerializer dataSerializer) {
            // open SQL connection
            String = dataSerialize.serialize();
            // do sqlPersistanceLogic
        }
    }
    
    class FtpDestination implements Destination {
        final String username;
        ...
        ...
    
        FtpDestination(String username, String password, String url) {
            this.username = username;
            ...
            ...
        }
    
        void persist(DataSerializer dataSerializer) {
            // open FTP session connection
            String = dataSerialize.serialize();
            // send to ftpDestination
        }
    }
    
    Call:
    
    Destination dest = getApropriateDestination();
    dest.persist(new XmlSerializer(rawData));
    

    您还可以实现逻辑来验证特定目的地支持的序列化程序,或者如果目的地和序列化程序之间存在1:1的关系,您可以使用模板。但我不知道它在C语言中是怎样的;

    根据您使用的工具和框架,您可以实现三种建议方式之一。原则仍然存在

  • 沃盛
    2023-03-14

    您可能希望获得一份现代C设计的副本,以了解如何制作一个基于策略的通用转换工具。下面是一个非常粗略的框架,它由两个策略参数化:格式和连接。

    template
    <
        typename FormatPolicy,    // SQL, XML, CSV, provides row, config functionality
        typename ConnectionPolicy // SQL, FTP, provides open/close/read/write functionality
    >
    class ConversionTool
    : 
        public FormatPolicy,
        public ConnectionPolicy
    {
    public:
        // your conversion interface here
        void operator()( /* your input */, /* your output */);
    };
    
    class SQLFormat { // SQL specific stuff } ;
    class SQLConnection { // SQL specific stuff };
    
    typedef ConversionTool<SQLFormat, SQLConnection> SQL2OurCustomerSQL;
    SQL2OurCustomerSQL()(in_file, out_file); // for elsewhere declared in_file / out_file
    
    钮巴英
    2023-03-14

    听起来你是在正确的道路上。

    应避免创建作为编写器和连接组合的类,而是创建某种包含(作为属性)编写器接口和连接接口的管理器类。然后创建每个实现的相应实现,并将它们传递到管理器中。

    这是策略设计模式的经典用法。

    编辑:添加代码示例。您应该添加适当的错误检查。

    class Writer
    {
    public:
        virtual void output(cons std::string &data) = 0;
    };
    
    class Format
    {
    public:
        virtual std::string serialize() = 0;
    };
    
    // Create concrete Writer and Format classes here
    
    class OutputManager
    {
    public:
        // Notice there should be no Writer, Format creation logic here,
        // This class should focus on orchestrating the output
        OutputManager() : writer_(NULL), format_(NULL) {}
        OutputManager(Writer *w, Format *f) : writer_(w), format_(f) {}
    
        void setWriter(Writer *w) { writer_ = w; }
        Writer *getWriter()       { return writer_; }
    
        void setFormat(Format *f) { format_ = f; }
        Format *getFormat()       { return format_; }
    
        // Maybe this should have a different return type
        void doOutput()
        {
            // Not sure what else you would need here,
            // but this is an example usage
            writer_->output(format_->serialize());
        }
    
    private:
        Writer *writer_;
        Format *format_;
    };
    
    //
    // And now the factories
    //
    class OutputAbstractFactory
    {
    public:
        OutputAbstractFactory(Config *c) config_(c) {}
        void createFactories()
        {
            writerFactory_ = WriterAbstractFactory::getWriterFactory(config_);
            formatFactory_ = FormatAbstractFactory::getFormatFactory(config_);
        }
    
        Writer *getWriter() { return writerFactory_->getWriter(); }
        Format *getFormat() { return formatFactory_->getFormat(); }
    
    private:
        WriterAbstractFactory *writerFactory_;
        FormatAbstractFactory *formatFactory_;
        Config *config_;
    }
    
    class WriterAbstractFactory
    {
    public:
        // Config is a class you will have to make with 
        // the info detailing the Writer and Format stuff
        static WriterAbstractFactory *getWriterFactory(Config *c);
        virtual Writer *getWriter() = 0;
    };
    
    class FormatAbstractFactory
    {
    public:
        // Config is a class you will have to make with
        // the info detailing the Writer and Format stuff
        static FormatAbstractFactory *getFormatFactory(Config *c);
        virtual Format *getFormat() = 0;
    };
    
    // Create concrete factories here
    
    //
    // And this ties it all together
    //
    int main(int argc, char **argv)
    {
        Config c;
        // populate Config accordingly
    
        OutputAbstractFactory *factory(&c);
        factory.createFactories();
    
        Writer *w = factory->getWriter();
        Format *f = factory->getFormat();
        // Do whatever else you need to with the Writer/Format here
    
        OutputManager om(w, f);
        // Do whatever else you need with the OutputManager here
        om.doOutput();
    }
    
     类似资料:
    • 需求描述 有一个项目,面向学校德育评价,其数据库中有如下表结构: 用户登录表:含一个“个人信息”字段,该字段依赖于下面的用户信息表 用户信息表:根据需求,分为学生表、教师表、运维表 ps:考虑到后期程序的灵活性及学校的发展性,可能后期运维人员可能会陆续增加,所以单独设置了运维表 问题描述 首先因为上面说到的缘故,为了兼顾后期项目的灵活性问题【后面运维人员可能不止一个】,不考虑常用的预分配运维账号的

    • 我正在写一个库在Java,我需要转换(地图)一个模型到另一个,反之亦然。我所做的是实现了一个包含两个泛型类型的抽象转换器类,包含convertTo和convertFrom方法,并从它扩展了我的转换器。 但是对于特定的实现,我可能还需要其他对象来进行转换,我不知道什么是实现这些东西的最佳实践。我想过适配器和门面,但他们似乎不符合我的要求。有没有一个设计模式我可以用来做这个?提前谢谢你。

    • 问题内容: 我有一个名为GoogleWeather的类,我想将其转换为另一个CustomWeather类。 有没有可以帮助您转换类的设计模式? 问题答案: 需要做出一个关键决定: 您是否需要转换生成的对象以反映对源对象的将来更改? 如果您不需要这样的功能,那么最简单的方法是将实用程序类与静态方法一起使用,这些静态方法根据源对象的字段创建新对象,如其他答案所述。 另一方面,如果您需要转换后的对象来反

    • 这个问题在我的项目中经常出现。作为一个例子,假设我有两个接口,一个从API检索信息,另一个解析这些信息。 现在,我可能需要有不同的API,因此我将有许多的实现,但每个实现都需要自己的。 这看起来与Bridge设计模式所建议的非常相似,但是该模式允许任何APIClient使用任何APIParser(我说的对吗?) 那么,有没有更好的解决方案呢?或者也许这很好,不需要重构它。 另外,也许parse不是

    • 有一个独立的Java应用程序。其中有一个工厂方法,只调用一次,只创建一个对象(如果可能的话)。我有两个问题--哪种模式对此更好?其次,在这种情况下,将创建工厂的对象存储在工厂本身中是正确的吗?

    • 本文向大家介绍当拿到一个新的项目,让你对这个项目的css做下架构设计,你该如何下手?相关面试题,主要包含被问及当拿到一个新的项目,让你对这个项目的css做下架构设计,你该如何下手?时的应答技巧和注意事项,需要的朋友参考一下 公共变量(主题色/主要空隙/主要字号字体等) 编译器(scss/less/postcss/stylus) 自适应方案(栅格/rem/vw/pt) 目录约定(mixin/comm