Moment For Technology

Design patterns (implemented functionality, equivalent to a record of use scenario + principle level implementation)

Posted on Aug. 8, 2022, 7:07 p.m. by Scott Ortiz
Category: reading Tag: Design patterns

Summary of design pattern: Design pattern is the use of inheritance between classes, interfaces, class aggregation, combination of relations, to achieve a good extension structure

Create a model

Singleton pattern: Method of creating a single instance

In factory mode, the creation of complex objects is left to the factory, and users do not care about the creation process

In the simple factory pattern, the factory creates different objects depending on the values passed in

Factory pattern: The factory is an abstract class, only common functions, personalized factory function implementation, subclass factory implementation

Abstract Factory pattern: Factories and created objects are abstract methods that are implemented by subclasses

Builder mode: Object creation is guided by Derctor, the actual creation is left to the builder, the builder aggregates to Derctor, and the creation process can be modified

Prototype mode: Clone objects using clone technology or deserialization method, that is, created objects will not be modified because of the original object

Behavior pattern: Adapter pattern: Class extensions to desired classes by clients decorator pattern: Enhancements to class-induced functionality It is divided into generic methods and personalized methods. Personalized methods need to be implemented, aggregated into factory classes, which are composed of containers. For the same objects that have been created, only the proxy pattern (thread private pool) is obtained in the container: the function of the original class is extended

Behavior pattern: template pattern; Template methods are abstract methods, and with template implementation methods, subclasses simply implement personalized methods

Observer mode (passively triggered observer) Method of triggering an observer when the observer has a state change

The policy pattern (actively triggered policy) uses the aggregate policy approach directly

Principles of design pattern: 1. Single responsibility principle (different functional modules are implemented by different classes or methods) (purpose: If the program is not very complex, it needs to follow a single principle. 2. Interface isolation principle (each class depends on (uses) the interface, in which the methods must be used. Low-level code interfaces, abstract classes, variables, use interfaces whenever possible (extension of functionality is possible)

3, dependency inversion principle (interface oriented programming, detail depends on abstraction, not abstraction depends on detail, low level depends on high level) three ways of dependenceInterface implementationConstructor implementationSet method implementation 4, Lee's substitution principle to minimize the rewrite of the parent class, which will reduce the reusability of the program, especially in the scenario of frequent use of polymorphism

The workaround is that subclasses and superclasses inherit from higher parent classes, using dependency, aggregate combinations instead

5, open and close principle (for extension development, for modification closed) new functions try to add new code rather than modify the original code, such as adding new functions, creating new classes, passing in fixed classes, rather than changing fixed classes

6, Demeter's law of dependence on their own class, the less you know the better, methods as much as possible encapsulated in their own class, other classes simply call as far as possible to avoid direct variables involving other classes

The principle of composite reuse (try to use composite synthesis rather than inheritance directly) is to use set methods, constructor methods, or new instead of inheriting classes

unl Relationships between classes: dependencies (class A uses B, then A depends on B) generalization (inheritance) implementation (interface implementation) association (whether member variables are defined) aggregation (only other classes are declared in a class) divisible composition (other classes are created in a class) indivisible

Classification of design patterns

The purpose of design mode is to improve the maintainability and expansibility of the software system and reduce the code complexity of the system

Singleton pattern, Factory pattern, Abstract Factory pattern, Builder pattern, Prototype pattern, Decorator pattern, Adapter pattern, Bridge pattern, share pattern

The singleton pattern

Hungry (static variable)

Constructor privatized (prevents new) class internally created objects from being exposed to static method getInstance advantage: created at class load time, avoids multi-threading problems, simple implementation disadvantage: class does not have to be loaded only at getInstance time, may waste memory resources

The constructor is privatized to avoid using new methods to create multiple objects, while the class can be called internally to create objects. Static methods are used for exposed methods to ensure that methods of that class are accessible,

Lazy loading uses double checking

Static inner classes implement the singleton pattern

Static inner classes are not loaded when the class is loaded. Instance objects are executed only when methods are used

Scenarios used by the singleton pattern: frequently used objects

The factory pattern

Of simple factory pattern (object created by the factory according to the incoming symbol type) and create different types of factory factory need return object, depending on the type of the incoming this object is frequently modified, the caller is frequently used by multiple places, so that the use of the customer class and factory is low coupling, modify the factory class, You don't have to modify the client class a lot

Factory model; Compared with the simple factory pattern, factory as an abstract class, only common function, the implementation of specific factory function, to a subclass of the factory, and factory portfolio to the client class crder class, relative to the simple factory pattern, factory pattern are more scalability for the factory, concrete factory implementation function call, (client class abstract classes, with the combination of)

The abstract factory class is an interface that has subclasses to implement. The abstract interface. The Order class aggregates the abstract factory.

Usage scenarios: 1. When you do not know the exact type of object to use. 2

Advantages:

Decouple the specific product from the creator

Consistent with the principle of single responsibility

In line with the open and close principle

public class designermodal{ public static void main(String[] args) { Application2 application2 = new createproductA(); Product product = application2.GetObject(); // Product is polymorphic, although product.method1() is called; , but executes different product.method1() methods depending on the implementation class; }}Copy the code
interface Product {
    public void method1();
}
Copy the code
abstract class Application2{ abstract Product creatproduct(); Product GetObject(){ Product product = creatproduct(); return product; }}Copy the code
class createproductA1 extends Application2{ @Override Product creatproduct() { return new productA(); } } class createproductA extends Application2{ @Override Product creatproduct() { return new productB(); } } class productA implements Product{ public void method1(){ System.out.println("method1"); } } class productB implements Product{ public void method1(){ System.out.println("method2"); }}Copy the code

The abstract factory pattern (the factory and the factory methods are interfaces, made up of new requirements, and only need to implement these methods) has the following advantages: 1. It can be determined that the methods obtained from the factory are compatible with each other

2. Avoid tight coupling between client code and production code

3, in line with the principle of single responsibility

4, in line with the open and close principle

public class abstractfactory { public static void main(String[] args) { databaseutil idatabaseutil = new oracleDatabaseUtil(); Iconnection connection = idatabaseutil.getConnection(); connection.connect(); Icommand icommand = idatabaseutil.getIcommand(); icommand.command(); } } interface Iconnection{ void connect(); } interface Icommand{ void command(); } // Abstract factory mode, factory method interface (methods and classes are made up of interfaces) interface databaseutil{Iconnection getConnection(); Icommand getIcommand(); } class MySqlConnection implements Iconnection{ @Override public void connect() { System.out.println("mysql connected."); } } class MySqlCommond implements Icommand{ @Override public void command() { System.out.println("mysql command."); } } class mysqlDatabaseUtil implements databaseutil{ @Override public Iconnection getConnection() { return new MySqlConnection(); } @Override public Icommand getIcommand() { return new MySqlCommond(); } } class oracleconmand implements Icommand{ @Override public void command() { System.out.println("oracleconnect."); } } class oracleconnect implements Iconnection{ @Override public void connect() { System.out.println("oracleconmand"); } } class oracleDatabaseUtil implements databaseutil{ @Override public Iconnection getConnection() { return new oracleconnect(); } @Override public Icommand getIcommand() { return new oracleconmand(); }}Copy the code

Builders mode: (specialconcreateprobuider polymerization to director, director for parameters, internal call specialconcreateprobuider create methods to create objects)

Pros and cons: The user does not need to know the complexity of the creation process

Usage scenario: You can build different things without knowing how to build them. In the process of building a map, the user delegates the Director class to build objects

Object creation is more complex, specialconcreateprobuider (object) is responsible for creating need individualized need to create the initializer director (responsible for incoming parameters) can share, know the object creation

Advantages: Independent builder, easy to expand

The difference between the factory method and the builder method: Both aim to create a complex object. The factory mode focuses on the whole object creation method, while the builder mode focuses on the object creation process, which can be invoked freely at creation time.

package main.java; public class productModel { public static void main(String[] args) { productbuilder specialconcreateprobuider = new specialconcreateprobuider(); Director director = new Director(specialconcreateprobuider); product product = director.makeProductor("aa", "bb", "cc", "dd", "ee", "ee"); System.out.println(product); } } class Director{ private productbuilder builder; public Director(productbuilder builder) { this.builder = builder; } public product makeProductor(String productname, String productcompany, String part1, String part2, String part3, String part4){ builder.builderProductcompany(productname); builder.builderProductname(productcompany); builder.builderProductpart1(part1); builder.builderProductpart2(part2); builder.builderProductpart3(part3); builder.builderProductpart4(part4); product build = builder.build(); return build; } } interface productbuilder{ void builderProductname(String Productname); void builderProductcompany(String Productcompany); void builderProductpart1(String part1); void builderProductpart2(String part2); void builderProductpart3(String part3); void builderProductpart4(String part4); product build(); } class defualtconcreateprobuider implements productbuilder{ private String Productname; private String Productcompany; private String part1; private String part2; private String part3; private String part4; @Override public void builderProductname( String Productname ) { this.Productname =Productname; } @Override public void builderProductcompany( String Productcompany) { this.Productcompany =Productcompany; } @Override public void builderProductpart1(String part1) { this.part1 = part1; } @Override public void builderProductpart2(String part2) { this.part2 = part2; } @Override public void builderProductpart3(String part3) { this.part3 = part3; } @Override public void builderProductpart4(String part4) { this.part4 = part4; } @Override public product build() { return new product(this.Productname,this.Productcompany,this.part1,this.part2 ,this.part3, this.part4); } } class specialconcreateprobuider implements productbuilder{ private String Productname; private String Productcompany; private String part1; private String part2; private String part3; private String part4; @Override public void builderProductname( String Productname ) { this.Productname =Productname; } @Override public void builderProductcompany( String Productcompany) { this.Productcompany =Productcompany; } @Override public void builderProductpart1(String part1) { this.part1 = part1; } @Override public void builderProductpart2(String part2) { this.part2 = part2; } @Override public void builderProductpart3(String part3) { this.part3 = part3; } @Override public void builderProductpart4(String part4) { this.part4 = part4; } @Override public product build() { return new product(this.Productname,this.Productcompany,this.part1,this.part2 ,this.part3, this.part4); } } class product{ private String Productname; private String Productcompany; private String part1; private String part2; private String part3; private String part4; public product() { } public product(String productname, String productcompany, String part1, String part2, String part3, String part4) { Productname = productname; Productcompany = productcompany; this.part1 = part1; this.part2 = part2; this.part3 = part3; this.part4 = part4; }}Copy the code

Constructor mode 2 Product2 class Builder() static class insert values, static methods. Perform create

Application Scenarios:

The object that needs to be generated has a complex internal structure and the internal properties of the object that need to be generated themselves depend on each other to work with immutable objects

package main.java; public class productModel2 { public static void main(String[] args) { product2 bulid = new product2.Builder().Productname("aa").part1("bb").bulid(); System.out.println(bulid); } } class product2 { private final String Productname; private final String Productcompany; private final String part1; private final String part2; private final String part3; private final String part4; static class Builder{ private String Productname; private String Productcompany; private String part1; private String part2; private String part3; private String part4; public Builder Productname(String productname) { this.Productname = Productname; return this; } public Builder part1(String part1) { this.part1 = part1; return this; } public Builder part2(String part2) { this.part2 = part2; return this; } public Builder part3(String part3) { this.part3 = part3; return this; } public Builder part4(String part4) { this.part4 = part4; return this; } product2 bulid(){ return new product2(this.Productname,this.Productcompany,this.part1,this.part2,this.part3,this.part4); } } public product2(String productname, String productcompany, String part1, String part2, String part3, String part4) { Productname = productname; Productcompany = productcompany; this.part1 = part1; this.part2 = part2; this.part3 = part3; this.part4 = part4; } @Override public String toString() { return "product2{" + "Productname='" + Productname + '\'' + ", Productcompany='" + Productcompany + '\'' + ", part1='" + part1 + '\'' + ", part2='" + part2 + '\'' + ", part3='" + part3 + '\'' + ", part4='" + part4 + '\'' + '}'; }}Copy the code

Prototype mode (the purpose is to copy the prototype object, but the copied object is independent of the original object, i.e. the reference object is different, when modifying the copied object, the original object will not change)

Prototype instances specify the types of objects to be created, and create new objects by copying them (shallow copies are required if they are mutable or primitive data types, such as String). If there is a mutable object in an object, the object needs to be deep-copied.)Shallow copy: refers only to PointersDeep copy: Copies an object

The clone method and serialization method are implemented

Clone is the use of Java clone, a copy of the object

Serialization is the output and input of the object, and the pointer is assigned to the current value for deep copy

Serialization method

Clone method

 product3 clone = (product3) super.clone();
        BaseInfo clone1 = (BaseInfo) this.baseInfo.clone();
        clone.setBaseInfo(clone1);
Copy the code

package main.java;

public class yxms {
    public static void main(String[] args) throws CloneNotSupportedException {
        BaseInfo gg = new BaseInfo("gg");
        product3 product3 = new product3("a", "b", "c", "d", "e", "f",gg);
        product3 clone = product3.clone();
        clone.getBaseInfo().setCompanyname("aaaaaa");
        clone.setPart1("bbbbbbbbbbbbbbbb");
        System.out.println(product3);
        System.out.println(clone);
    }
}

class BaseInfo implements Cloneable{
    private String companyname;

    public BaseInfo(String companyname) {
        this.companyname = companyname;
    }

    public String getCompanyname() {
        return companyname;
    }

    public void setCompanyname(String companyname) {
        this.companyname = companyname;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return super.hashCode()+"BaseInfo{" +
                "companyname='" + companyname + '\'' +
                '}';
    }
}

class product3 implements  Cloneable{
    private String Productname;
    private String Productcompany;
    private String part1;
    private String part2;
    private String part3;
    private String part4;
    private BaseInfo baseInfo;

    public BaseInfo getBaseInfo() {
        return baseInfo;
    }

    public void setBaseInfo(BaseInfo baseInfo) {
        this.baseInfo = baseInfo;
    }

    public String getProductname() {
        return Productname;
    }

    public String getProductcompany() {
        return Productcompany;
    }

    public String getPart1() {
        return part1;
    }

    public String getPart2() {
        return part2;
    }

    public String getPart3() {
        return part3;
    }

    public String getPart4() {
        return part4;
    }

    public product3() {

    }

    public void setProductname(String productname) {
        Productname = productname;
    }

    public void setProductcompany(String productcompany) {
        Productcompany = productcompany;
    }

    public void setPart1(String part1) {
        this.part1 = part1;
    }

    public void setPart2(String part2) {
        this.part2 = part2;
    }

    public void setPart3(String part3) {
        this.part3 = part3;
    }

    public void setPart4(String part4) {
        this.part4 = part4;
    }

    @Override
    protected product3 clone() throws CloneNotSupportedException {
        product3 clone = (product3) super.clone();
        BaseInfo clone1 = (BaseInfo) this.baseInfo.clone();
        clone.setBaseInfo(clone1);
        return clone;
    }

    public product3(String productname, String productcompany, String part1, String part2, String part3, String part4,BaseInfo baseInfo) {
        Productname = productname;
        Productcompany = productcompany;
        this.part1 = part1;
        this.part2 = part2;
        this.part3 = part3;
        this.part4 = part4;
        this.baseInfo = baseInfo;
    }

    @Override
    public String toString() {
        return super.hashCode()+"product3{" +
                "Productname='" + Productname + '\'' +
                ", Productcompany='" + Productcompany + '\'' +
                ", part1='" + part1 + '\'' +
                ", part2='" + part2 + '\'' +
                ", part3='" + part3 + '\'' +
                ", part4='" + part4 + '\'' +
                ", baseInfo=" + baseInfo +
                '}';
    }
}
Copy the code

Share mode: the actual String, pool technology is used to consolidate the common features of the same code instance (if not, create, if yes, use the original) all share elements will be stored in a container.Figure shows:

Flyweight: abstract class, abstract class of products, at the same time defines the public methods of the abstract * (internal state) and the method of individuation (external) interface or implementation concreatFlyweight: the realizing methods of the flyweight unsharedConcretaFlyweight: The flyweightFactory method implements personalization: a meta-factory class that builds pool containers (collections) and provides methods to get objects from the pool

Implementation of the description: websiteFactory responsible for building pool container (set), at the same time provide the method of object from the pool to get unsharedConcretaFlyweight = user concreatFlyweight = website

public class xyms { public static void main(String[] args) { websiteFactory websiteFactory = new websiteFactory(); Website website = websiteFactory. Getwebsitecatory (" news "); Website website2 = websiteFactory. Getwebsitecatory (" 2 "); website.use(new user("nbb")); website2.use(new user("nxx")); System.out.println(websiteFactory.getpoolsize()); } } class user{ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public user(String name) { this.name = name; } @Override public String toString() { return "user{" + "name='" + name + '\'' + '}'; } } abstract class website{ abstract public void use(user a); } class Concreatwebsite extends website{ private String type=""; public Concreatwebsite(String type) { this.type = type; } @Override public void use(user a) { System.out.println("Concreatwebsite"+type+a); Class websiteFactory{private HashMapString,website pool = new HashMap(); Public website getWebsitecatory (String type){if(! pool.containsKey(type)){ pool.put(type,new Concreatwebsite(type)); } return pool.get(type); } public int getPoolSize (){return pool.size(); }}Copy the code

Integer implementation of the meta schema

Facade pattern: Reduces the complexity of using classes 1, 2, and 3 to implement a function. Facade pattern uses a facade to manage the classes below, and the client only needs to look at the facade, not the implementation classes inside

Advantages: The client does not need to connect the complex calls at the bottom, reducing the complexity of starting services

public class mmmshi { public static void main(String[] args) { facades facades = new facades(); facades.dosomething(); } } class facades{ subsystem1 subsystem = new subsystem1(); subsystem2 subsystemb = new subsystem2(); subsystem3 subsystemc = new subsystem3(); public void dosomething(){ subsystem.method1(); subsystemb.method1(); subsystemc.method1(); } } class subsystem1{ public void method1(){ System.out.println("method1"); } } class subsystem2{ public void method1(){ System.out.println("method2"); } } class subsystem3{ public void method1(){ System.out.println("method3"); }}Copy the code

Adapter pattern :(enhancements to existing classes (aggregated into adapters, enabling extensions to functionality))

Object is configuration mode: implementation method, adapter adpter to get the object adaptee, after processing, output

Usage scenarios: 1. Use the adapter pattern when you want to use some existing classes whose interfaces are incompatible with other code

2. Use this pattern when you want to reuse several existing subclasses that lack common functionality that cannot be added to the superclass

Object adapter pattern

public class adapter1 { public static void main(String[] args) { Target adapter = new Adapter(new adaptee()); int i = adapter.output5v(); System.out.println(i); } } class adaptee{ public int output220(){ return 220; } } interface Target{ int output5v(); } class Adapter implements Target{ private adaptee aa; public Adapter(adaptee aa) { this.aa = aa; } @Override public int output5v() { int i = aa.output220(); // match I return i-100; }}Copy the code

Inheriting the implementation adapter pattern (the adapter inherits the Adapee, exposing the shortcomings of other methods)

Decorator pattern: Attaches functionality to an object without modifying the source object

Implementation method:

Define the standard abstract class Component. The existing functionality inherits the abstract class

Decorators inherit from Component, constructors pass in the Component class, and concreaderector is an option for multi-function enhancements

Component: Extract decorator

Decoretor: Decorator class, which contains objects to be decorated. Because decorator and decorator inherit from the same abstract class, there is no effect on external code. Through decorator, you can modify the property values of the decorator

Advantages and disadvantages: You can extend the functionality of an object without modifying an existing object or creating a subclass of the object. You can dynamically add or delete multiple extension functions. You can extend different decorators to solve the problem of extending different functions. Disadvantages: Multi-layer decoration will be more complex, and it is impossible to control the order of decoration

The difference between the Decorator Pattern and the adapter Pattern: The Decorator Pattern is a structural Pattern that attaches functionality to an object without changing the original object, providing a more flexible alternative to inheritance (extending the functionality of the original object). Used to extend the functionality of a class or add additional responsibilities to a class. 2. Add functions to an object dynamically, which can be undone dynamically.

Adapter Pattern refers to the transformation of an interface of a class into another interface expected by the customer, so that classes incompatible with the original interface can work together. It belongs to the structural design Pattern.

package main.java.sjms; public class decoreationtest1 { public static void main(String[] args) { Drink coffeB = new Chocolate(new Chocolate(new Milke(new CoffeB()))); System.out.println(coffeB.des()); System.out.println(coffeB.cost()); } } abstract class Drink{ private float price; public String des; public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } public String getDes() { return des; } public void setDes(String des) { this.des = des; } public abstract float cost(); public abstract String des(); } class Coffe extends Drink{ @Override public float cost() { return super.getPrice(); } @Override public String des() { return super.getDes(); }} class CoffeB extends Coffe{public CoffeB() {setPrice(1.0f); SetDes (" black card "); }} class CoffeC extends Coffe{public CoffeC() {setPrice(1.0f); SetDes (" white card "); }} class CoffeD extends Coffe{public CoffeD() {setPrice(1.0f); SetDes (" aa "); } } class Decorator extends Drink{ private Drink obj; public Decorator(Drink obj) { this.obj = obj; } public float cost() { return obj.cost()+super.getPrice(); } @Override public String des() { return super.getDes()+"%%"+obj.des() ; } } class Chocolate extends Decorator{ public Chocolate(Drink obj) { super(obj); SetDes (" chocolate "); SetPrice (1.0 f); } } class Milke extends Decorator{ public Milke(Drink obj) { super(obj); setDes("Milke"); SetPrice (1.0 f); } } class doujain extends Decorator{ public doujain(Drink obj) { super(obj); setDes("doujain"); SetPrice (1.0 f); }}Copy the code

implementation

Bridge mode (two groups of classes, so that the classes of one group provide aggregation to the other group, preventing class explosion)

Usage scenario: Suitable for two groups of classes will be frequently added, there are dependencies between each other

Problem: In the case shown below, because each open form of the collection will add new features to the phones, and also add a series of phones, there will be class explosion

The design structure of the above figure 1 is replaced by that of Figure 2, so that the model and brand of mobile phone can be reused

It is implemented by aggregating different brands into different models of mobile phones

Proxy mode:

Static proxy (aggregating classes into a proxy class that processes the aggregated class method before and after it executes)

Dynamic proxy; The constructor is used to inject the implemented class into the proxy's class, whose implementation calls the proxy. NewProxyInstance implements the proxy method on an object.

Dynamic proxy factory, the following method is JDK's own proxy method, the target method passed in, in the creation of a factory, instance object passed into the factory, call the factory method, you can achieve dynamic proxy

Cglib generation (inherit the MethidInterceptor class and implement the Intercepter method to perform the proxy on the target proxy object in getProxyInstance) Final classes cannot be propped, and static methods that target methods are static will not be propped

Difference: The JDK's proxy implementation uses reflection to instantiate proxy objects in conjunction with the classloader. Cglib uses ASM to convert bytecode to generate new classes

The (frequently used) template method pattern (template methods are implemented in abstract classes, used in concrete ways, and implemented by inherited subclasses) avoids the need to write duplicate code when calling methods that use the parent class for template methods and that use the subclass for custom methods

Template methods are put into hook methods, and empty methods are designed to be implemented by subclasses. If they are not implemented, they are not executed

The principle of implementation: inherit template method, need to implement the class by the subclass implementation

The purpose of an empty method is for subclasses to override it

Observer pattern (triggered by the observed action, passively triggered) : Subject relies on multiple Observer instances. Weatherdata registers all ObservCE implementation classes through interface Observer data

Implementation principle: The observed aggregates subscribers, the observed has the function of registering, deleting, and notifying (call the registered class method).

Implementation: the observer class aggregation to be observed in the array of classes, if the observed class to execute the updated method, call the aggregation class display data method, realize the observation of data changes, while the observer has the function of removing the registered class

Usage scenario: Publish and subscribe

Policy mode :(method of directly triggering policies, active triggering) policies are passed to the principal by aggregation (used in dubbo's policy transformation)

Implement methods: By aggregating the classes of methods that need to be executed into the current class and invoking methods (i.e., policies) in the current class

Scenario :(free toggle method of a class) (toggle method in another class, pass in the object via aggregation, and execute the method internally)

Responsibility chain mode: Usage scenario: when the processing of a request needs to be carried out in different functional areas according to different situations, you can use this responsibility chain mode to design the program

Methods used

The following Approver is a handler: (1) It has an Approper attribute that the next handler can rely on; (2) it has an abstract method that can handle the request

The implementation subclass writes the specific request handling method, and if it cannot handle it, executes the dependent implementation subclass

In the actual call, depending on the order, the implementation subclasses are relied on

Search
About
mo4tech.com (Moment For Technology) is a global community with thousands techies from across the global hang out!Passionate technologists, be it gadget freaks, tech enthusiasts, coders, technopreneurs, or CIOs, you would find them all here.